diff --git a/CompleteApps/SmartKettleApp/README_zh.md b/CompleteApps/SmartKettleApp/README_zh.md new file mode 100644 index 0000000000000000000000000000000000000000..bd65dd7f7976aed01c3050c49c35a6ca89808258 --- /dev/null +++ b/CompleteApps/SmartKettleApp/README_zh.md @@ -0,0 +1,37 @@ +# 智能热水壶手机端代码介绍 + +### 简介 + +本Sample是手机端应用,结合智能热水壶设备端[参考](https://gitee.com/openharmony/app_samples/tree/master/CompleteApps/SmartKettleDevice/),模拟开发一个手机应用和水壶的联动方案。手机端主要包括:手机端给设备端配网、发送控制消息给设备端、并接受设备侧消息等。 + +### 使用说明 + +##### 1.代码编译运行步骤 + +1)提前准备好搭载HarmonyOS系统的手机; + +2)下载此项目,编译构建请参考[链接]( https://developer.harmonyos.com/cn/docs/documentation/doc-guides/build_overview-0000001055075201 ); + +3)用户需新建工程,并将代码中原来的包名替换为新建包名; + +4)真机运行应用请参考[链接]( https://developer.harmonyos.com/cn/docs/documentation/doc-guides/run_phone_tablat-0000001064774652 )。 + +##### 2.与设备端联动步骤 + +1)提前准备好[智能热水壶设备端](https://gitee.com/openharmony/app_samples/tree/master/CompleteApps/SmartKettleDevice/),可参考智能热水壶设备端介绍; + +2)打开FA,在热点连接列表中找到Kettle_AP热点并连接,点击开始配网,选择好热点并输入密码点击确定给设备端配网; + +3)在设备端配网成功后,可控制设备开关机、设备不同的烧水模式、比如50度冲奶,80度泡茶,点击加热升至/煮沸降至 保温温度按钮,才是发送消息给设备端; + +4)并根据时间自动将加热到指定的温度,比如早上8点一杯温水,下午16点泡花茶80度水等;还能定时提醒主人喝水; + +### 约束限制 + +1. 提前准好已实名认证的开发者联盟账号 ,具体[参考](https://developer.huawei.com/consumer/cn/) + +2. 开发工具:DevEcoStudio [参考](https://developer.harmonyos.com/cn/develop/deveco-studio#download /) + +3. 本示例需在真机运行,请提前准备好搭载HarmonyOS系统的手机。 + +4. 更多资料请登录HarmonyOS应用开发官网: https://developer.harmonyos.com/cn/ \ No newline at end of file diff --git a/CompleteApps/SmartKettleApp/build.gradle b/CompleteApps/SmartKettleApp/build.gradle new file mode 100644 index 0000000000000000000000000000000000000000..bdcc1aaaa48521294e0947d0954ec5e5ca0bb002 --- /dev/null +++ b/CompleteApps/SmartKettleApp/build.gradle @@ -0,0 +1,38 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. +apply plugin: 'com.huawei.ohos.app' + +//For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#ZH-CN_TOPIC_0000001154985555__section1112183053510 +ohos { + compileSdkVersion 5 + defaultConfig { + compatibleSdkVersion 5 + } +} + +buildscript { + repositories { + maven { + url 'https://repo.huaweicloud.com/repository/maven/' + } + maven { + url 'https://developer.huawei.com/repo/' + } + jcenter() + } + dependencies { + classpath 'com.huawei.ohos:hap:2.4.4.2' + classpath 'com.huawei.ohos:decctest:1.2.4.0' + } +} + +allprojects { + repositories { + maven { + url 'https://repo.huaweicloud.com/repository/maven/' + } + maven { + url 'https://developer.huawei.com/repo/' + } + jcenter() + } +} diff --git a/CompleteApps/SmartKettleApp/entry/build.gradle b/CompleteApps/SmartKettleApp/entry/build.gradle new file mode 100644 index 0000000000000000000000000000000000000000..9cf779cd9d298f7f3e306c6eac2e0e00bd0def5f --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/build.gradle @@ -0,0 +1,27 @@ +apply plugin: 'com.huawei.ohos.hap' +apply plugin: 'com.huawei.ohos.decctest' +//For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#ZH-CN_TOPIC_0000001154985555__section1112183053510 +ohos { + compileSdkVersion 5 + defaultConfig { + compatibleSdkVersion 5 + } + buildTypes { + release { + proguardOpt { + proguardEnabled false + rulesFiles 'proguard-rules.pro' + } + } + } + +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar', '*.har']) + testImplementation 'junit:junit:4.13' + ohosTestImplementation 'com.huawei.ohos.testkit:runner:1.0.0.100' +} +decc { + supportType = ['html', 'xml'] +} diff --git a/CompleteApps/SmartKettleApp/entry/node_modules/fa-softaputil.js b/CompleteApps/SmartKettleApp/entry/node_modules/fa-softaputil.js new file mode 100644 index 0000000000000000000000000000000000000000..d31e80c19dbc161d3ce0e1f1f5975e782a82285d --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/node_modules/fa-softaputil.js @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +const injectRef = Object.getPrototypeOf(global) || global +injectRef.regeneratorRuntime = require('@babel/runtime/regenerator') +const CONSTANT = { + BUNDLE_NAME: "ohos.samples.smartkettle", + ABILITY_NAME_FOR_BM: "ohos.samples.smartkettle.ControlAbility", + ABILITY_NAME_FOR_MAIN: "ohos.samples.smartkettle.MainAbility", + ABILITY_NAME_FOR_CONTROL_SERVER: "ohos.samples.smartkettle.ControlServer", + TAG:"[Demo]:" +} + +const ABILITY_TYPE_EXTERNAL = 0; +const ABILITY_TYPE_INTERNAL = 1; +const ACTION_SYNC = 0; +const ACTION_ASYNC = 1; + +var FASoftapUtil = { + info: function (info) { + console.info(CONSTANT.TAG + info); + }, + + // Call PA to send command + sendMessage:async function(data, code){ + var action = {}; + action.bundleName = CONSTANT.BUNDLE_NAME; + action.abilityName = CONSTANT.ABILITY_NAME_FOR_CONTROL_SERVER; + action.messageCode = code; + action.data = data; + action.abilityType = ABILITY_TYPE_EXTERNAL; + action.syncOption = ACTION_SYNC; + var result = await FeatureAbility.callAbility(action); + return result; + }, + + // Pull up FA + callNewFa: async function (dataInfo, flag) { + var action = {}; + action.bundleName = CONSTANT.BUNDLE_NAME; + action.deviceType = 1; + if (flag === 0) { + action.abilityName = CONSTANT.ABILITY_NAME_FOR_BM; + } else if (flag === 1) { + action.abilityName = CONSTANT.ABILITY_NAME_FOR_MAIN; + } + action.data = dataInfo; + await FeatureAbility.startAbility(action); + }, + + subscribe: async function (code, callback){ + let action = {}; + action.bundleName = CONSTANT.BUNDLE_NAME; + action.abilityName = CONSTANT.ABILITY_NAME_FOR_CONTROL_SERVER; + action.messageCode = code; + action.abilityType = ABILITY_TYPE_EXTERNAL; + action.syncOption = ACTION_SYNC; + + var result = await FeatureAbility.subscribeAbilityEvent(action, function(callbackData) { + callback(callbackData); + }); + var ret = JSON.parse(result); + if (ret.code == 0) { + console.info('subscribe success, result:' + result); + } else { + console.error('subscribe error, result:' + result); + } + console.info('==Trash==subscribe---end---'); + } +}; + +module.exports = { + FASoftapUtil +}; \ No newline at end of file diff --git a/CompleteApps/SmartKettleApp/entry/node_modules/fan-constants.js b/CompleteApps/SmartKettleApp/entry/node_modules/fan-constants.js new file mode 100644 index 0000000000000000000000000000000000000000..512f9921e0405ba95f559874d4132f6150f53980 --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/node_modules/fan-constants.js @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +const CONSTANTS = { + CONTROL_CODE: 1001, + GET_CURRENT_WIFI_CODE: 2001, + SET_WIFI_CODE: 2002, + GET_AVAILABLE_WIFI_CODE: 2003, + SUBSCRIBE_CONTROL_STATE: 3001, + SMARTFAN_WIFI: "Kettle_AP" +} + +module.exports = { + CONSTANTS +}; \ No newline at end of file diff --git a/CompleteApps/SmartKettleApp/entry/src/main/config.json b/CompleteApps/SmartKettleApp/entry/src/main/config.json new file mode 100644 index 0000000000000000000000000000000000000000..b7c325b6f4c1422be5d3e44e124aa82278eb8e04 --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/config.json @@ -0,0 +1,122 @@ +{ + "app": { + "bundleName": "ohos.samples.smartkettle", + "vendor": "sample", + "version": { + "code": 1000000, + "name": "1.0.0" + } + }, + "deviceConfig": {}, + "module": { + "package": "ohos.samples.smartkettle", + "name": ".MyApplication", + "mainAbility": "ohos.samples.smartkettle.MainAbility", + "deviceType": [ + "phone" + ], + "distro": { + "deliveryWithInstall": true, + "moduleName": "entry", + "moduleType": "entry", + "installationFree": false + }, + "metaData": { + "customizeData": [ + { + "name": "hwc-theme", + "value": "androidhwext:style/Theme.Emui.Translucent.NoTitleBar" + } + ] + }, + "abilities": [ + { + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ], + "orientation": "unspecified", + "name": "ohos.samples.smartkettle.MainAbility", + "icon": "$media:icon", + "description": "$string:mainability_description", + "label": "$string:app_name", + "type": "page", + "launchType": "standard" + }, + { + "visible": true, + "name": "ohos.samples.smartkettle.ControlAbility", + "icon": "$media:icon", + "description": "$string:controlability_description", + "label": "$string:app_name", + "type": "page", + "launchType": "standard" + }, + { + "name": "ohos.samples.smartkettle.ControlServer", + "icon": "$media:icon", + "description": "$string:ControlServer_description", + "type": "service" + } + ], + "js": [ + { + "pages": [ + "pages/index/index", + "pages/phone/index", + "pages/otherWifi/index", + "pages/confignet/index", + "pages/locationset/index" + ], + "name": "default", + "window": { + "designWidth": 720, + "autoDesignWidth": false + } + }, + { + "pages": [ + "pages/device/index", + "pages/reminder/index", + "pages/interval/index", + "pages/timer/index", + "pages/service/index" + ], + "name": "control", + "window": { + "designWidth": 720, + "autoDesignWidth": false + } + } + ], + "reqPermissions": [ + { + "name": "ohos.permission.INTERNET" + }, + { + "name": "ohos.permission.GET_WIFI_INFO" + }, + { + "reason": "get Local Location", + "name": "ohos.permission.LOCATION", + "usedScene": { + "ability": [ + "ohos.samples.smartkettle.MainAbility", + "ohos.samples.smartkettle.ControlAbility", + "ohos.samples.smartkettle.ControlServer" + ], + "when": "always" + } + }, + { + "name": "ohos.permission.SET_WIFI_INFO" + } + ] + } +} \ No newline at end of file diff --git a/CompleteApps/SmartKettleApp/entry/src/main/java/ohos/samples/smartkettle/Const.java b/CompleteApps/SmartKettleApp/entry/src/main/java/ohos/samples/smartkettle/Const.java new file mode 100644 index 0000000000000000000000000000000000000000..af98f0c7bd116896f372c6a1b61995e864cfd9df --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/java/ohos/samples/smartkettle/Const.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ohos.samples.smartkettle; + +/** + * Const + * + * @since 2021--1-19 + */ +public class Const { + /** + * device IP + */ + public static final String IP = "192.168.5.1"; + + /** + * control port + */ + public static final int CONTROL_PORT = 8787; + + /** + * control port + */ + public static final int CONFIG_PORT = 8686; + + /** + * TWO means Full mode when FeatureAbility start + */ + public static final int TWO = 2; + + /** + * THREE means pop-up mode when FeatureAbility start + */ + public static final int THREE = 3; + + /** + * Key code + */ + public static final String KEY_CODE = "code"; + + /** + * error message + */ + public static final String KEY_ERROR = "errMsg"; + + private Const() { + } +} diff --git a/CompleteApps/SmartKettleApp/entry/src/main/java/ohos/samples/smartkettle/ControlAbility.java b/CompleteApps/SmartKettleApp/entry/src/main/java/ohos/samples/smartkettle/ControlAbility.java new file mode 100644 index 0000000000000000000000000000000000000000..cf7ff716c931a49f8d8c585adc308434a0750314 --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/java/ohos/samples/smartkettle/ControlAbility.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ohos.samples.smartkettle; + +import ohos.aafwk.content.Intent; +import ohos.aafwk.content.IntentParams; +import ohos.ace.ability.AceAbility; +import ohos.utils.zson.ZSONObject; + +/** + * ControlAbility + * + * @since 2021-01-19 + */ +public class ControlAbility extends AceAbility { + private static final String TAG = "[Demo]:ControlAbility"; + + @Override + public void onStart(Intent intent) { + // Start the current ability using Full mode, 2 means Full mode when FeatureAbility start. + intent.setParam("window_modal", Const.TWO); + + // Start control FeatureAbility. + setInstanceName("control"); + + String data = ZSONObject.toZSONString(intent); + LogUtil.info(TAG, "data==" + data); + + // JS pull up this FeatureAbility , __startParams means default ability pull up control ability + Object reBackObj = intent.getParams().getParam("__startParams"); + + // Get dataInfo value sessionId and set to control page. + if (reBackObj != null) { + ZSONObject reBackInfo = ZSONObject.stringToZSON((String) reBackObj); + String dataInfo = reBackInfo.getString("serverIp"); + LogUtil.info(TAG, "dataInfo= " + dataInfo); + if (dataInfo != null) { + setParams(intent, "dataInfo", dataInfo); + } + } + super.onStart(intent); + } + + @Override + public void onStop() { + super.onStop(); + } + + private void setParams(Intent intent, String tag, String tagInfo) { + IntentParams intentParams = intent.getParams(); + if (intentParams != null) { + intentParams.setParam(tag, tagInfo); + + // Set params to control FeatureAbility home page. + setPageParams(null, intentParams); + } + } +} diff --git a/CompleteApps/SmartKettleApp/entry/src/main/java/ohos/samples/smartkettle/ControlServer.java b/CompleteApps/SmartKettleApp/entry/src/main/java/ohos/samples/smartkettle/ControlServer.java new file mode 100644 index 0000000000000000000000000000000000000000..d7cdaf950c9c92dceab06670186ea9aba700b41d --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/java/ohos/samples/smartkettle/ControlServer.java @@ -0,0 +1,394 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ohos.samples.smartkettle; + +import ohos.aafwk.ability.Ability; +import ohos.aafwk.content.Intent; +import ohos.global.resource.Resource; +import ohos.rpc.IRemoteBroker; +import ohos.rpc.IRemoteObject; +import ohos.rpc.MessageOption; +import ohos.rpc.MessageParcel; +import ohos.rpc.RemoteException; +import ohos.rpc.RemoteObject; +import ohos.utils.zson.ZSONArray; +import ohos.utils.zson.ZSONObject; +import ohos.wifi.WifiDevice; +import ohos.wifi.WifiLinkedInfo; +import ohos.wifi.WifiScanInfo; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.net.Socket; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; + +/** + * ControlServer + * + * @since 2021-01-19 + */ +public class ControlServer extends Ability { + private static final String TAG = "[Demo]:ControlServer"; + private static final int SUCCESS = 200; + private static final int ERROR = 1; + private static final int GET_CURRENT_WIFI_CODE = 2001; + private static final int GET_AVAILABLE_WIFI_CODE = 2003; + private static final int SET_WIFI_CODE = 2002; + private static final int CONTROL_CODE = 1001; + private static final int SUBSCRIBE_CONTROL_STATE = 3001; + private static final int NUMBER_FF = 0xff; + private static final int NUMBER_55 = 0x55; + private static final int NUMBER_AA = 0xaa; + private static final int NUMBER_00 = 0x00; + private static final int NUMBER_100 = 100; + private final MyRemote remote = new MyRemote(); + private Socket socketDeviceListener = null; + private IRemoteObject controlStateRemoteObj = null; + + @Override + public void onStart(Intent intent) { + super.onStart(intent); + } + + @Override + public void onBackground() { + super.onBackground(); + } + + @Override + public void onStop() { + super.onStop(); + if (socketDeviceListener != null) { + try { + socketDeviceListener.close(); + socketDeviceListener = null; + } catch (IOException e) { + LogUtil.error(TAG, "", e); + } + } + } + + @Override + protected IRemoteObject onConnect(Intent intent) { + super.onConnect(intent); + return remote.asObject(); + } + + /** + * MyRemote + * + * @since 2021-01-19 + */ + class MyRemote extends RemoteObject implements IRemoteBroker { + MyRemote() { + super("ControlServer_MyRemote"); + } + @Override + public boolean onRemoteRequest(int code, MessageParcel data, MessageParcel reply, MessageOption option) { + String dataStr = data.readString(); + LogUtil.info("onRemoteRequest: code=", String.valueOf(code) + ";data=" + dataStr); + switch (code) { + // controlling device + case CONTROL_CODE: + control(reply, dataStr); + break; + // Get current wifi + case GET_CURRENT_WIFI_CODE: + // Get WLAN management objects + reply.writeString(getCurrentWifi()); + break; + + // Get available wifi + case GET_AVAILABLE_WIFI_CODE: + reply.writeString(getAvialableWifi()); + break; + + // Distribution network + case SET_WIFI_CODE: + config(reply, dataStr); + break; + case SUBSCRIBE_CONTROL_STATE: { + subscribe(reply, data); + break; + } + default: { + fault(reply, code); + break; + } + } + return true; + } + @Override + public IRemoteObject asObject() { + return this; + } + } + + private void control(MessageParcel reply, String dataStr) { + Map result = new HashMap(); + try { + reply.writeString(controlDevice(dataStr)); + } catch (IOException e) { + LogUtil.error(TAG, "", e); + LogUtil.error(TAG, e.getMessage()); + result.put(Const.KEY_CODE, ERROR); + result.put(Const.KEY_ERROR, e.getMessage()); + reply.writeString(ZSONObject.toZSONString(result)); + } + } + + private void config(MessageParcel reply, String dataStr) { + Map result = new HashMap(); + try { + reply.writeString(configNet(dataStr)); + } catch (IOException e) { + LogUtil.error(TAG, "", e); + LogUtil.error(TAG, e.getMessage()); + result.put(Const.KEY_CODE, ERROR); + result.put(Const.KEY_ERROR, e.getMessage()); + reply.writeString(ZSONObject.toZSONString(result)); + } + } + + private void subscribe(MessageParcel reply, MessageParcel data) { + Map result = new HashMap(); + controlStateRemoteObj = data.readRemoteObject(); + result.put(Const.KEY_CODE, 0); + reply.writeString(ZSONObject.toZSONString(result)); + } + + private void fault(MessageParcel reply, int code) { + Map result = new HashMap(); + result.put(Const.KEY_CODE, ERROR); + result.put(Const.KEY_ERROR, "Invalid code :" + code); + reply.writeString(ZSONObject.toZSONString(result)); + } + + /** + * Get available wifi + * + * @return + */ + private String getAvialableWifi() { + // Get WLAN management objects + WifiDevice wifiDevice = WifiDevice.getInstance(this); + + // Call the WLAN scanning interface + try { + boolean isScanSuccess = wifiDevice.scan(); + if (!isScanSuccess) { + ZSONObject jsonObj = new ZSONObject(); + jsonObj.put(Const.KEY_CODE, ERROR); + jsonObj.put(Const.KEY_ERROR, "Fail to getAvialableWifi scan result false"); + return jsonObj.toString(); + } + + // Call to get scan results + List scanInfos = wifiDevice.getScanInfoList(); + + ZSONObject jsonObj = new ZSONObject(); + jsonObj.put(Const.KEY_CODE, SUCCESS); + ZSONArray wifiArray = new ZSONArray(); + + // Take the BSSID as the dimension, so ssid is needed to remove duplicates + Set wifiSet = new HashSet<>(); + for (WifiScanInfo scanInfo : scanInfos) { + if (scanInfo.getSsid() == null || scanInfo.getSsid().trim().equals("") + || wifiSet.contains(scanInfo.getSsid())) { + continue; + } + ZSONObject jsonWifi = new ZSONObject(); + jsonWifi.put("ssid", scanInfo.getSsid()); + if (scanInfo.getSecurityType() == 0) { + jsonWifi.put("security", getString(ResourceTable.String_forpublic)); + } else { + jsonWifi.put("security", getString(ResourceTable.String_encrypt)); + } + wifiSet.add(scanInfo.getSsid()); + wifiArray.add(jsonWifi); + } + jsonObj.put("wifi", wifiArray); + return ZSONObject.toZSONString(jsonObj); + } catch (IllegalArgumentException e) { + ZSONObject jsonObj = new ZSONObject(); + jsonObj.put(Const.KEY_CODE, ERROR); + jsonObj.put(Const.KEY_ERROR, "Fail to getAvialableWifi" + e.getMessage()); + return jsonObj.toString(); + } + } + + /** + * controlling device + * + * @param dataStr The json string passed in from the front end, including the device serverIp + * @return Device response + * @throws IOException e + */ + private String controlDevice(String dataStr) throws IOException { + LogUtil.info(TAG, "" + dataStr); + ZSONObject obj = ZSONObject.stringToZSON(dataStr); + + // Device IP obtained using the interface + String serverIp = obj.getString("serverIp"); + LogUtil.info(TAG, "" + serverIp); + obj.remove("serverIp"); + Socket socket = new Socket(serverIp, Const.CONTROL_PORT); + dataStr = obj.toString(); + OutputStream out = socket.getOutputStream(); + out.write(dataStr.getBytes("UTF-8")); + + BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); + String str = in.readLine(); + in.close(); + LogUtil.info("onRemoteRequest controlDevice receive:", str); + socket.close(); + + if (socketDeviceListener == null) { + // Initialize device monitoring + initDeviceListener(serverIp); + } + + // The returned result currently only supports String. For complex structures, + // it can be serialized as a ZSON string and reported + Map result = new HashMap(); + result.put(Const.KEY_CODE, SUCCESS); + return ZSONObject.toZSONString(result); + } + + /** + * Get the currently connected wifi name + * + * @return name + */ + private String getCurrentWifi() { + WifiDevice wifiDevice = WifiDevice.getInstance(getContext()); + + // Call the WLAN connection status interface to determine whether the current device is connected to WLAN + boolean isConnected = wifiDevice.isConnected(); + if (isConnected) { + // Get Wi-Fi connection information + Optional linkedInfo = wifiDevice.getLinkedInfo(); + + // Get the SSID in the connection information + return linkedInfo.get().getSsid(); + } else { + return ""; + } + } + + /** + * Call socket to complete network configuration + * + * @param dataStr wifi account and password + * @return return + */ + private String configNet(String dataStr) throws IOException { + Socket socket = null; + OutputStream out = null; + BufferedReader in = null; + try (Resource resource = new Resource() { + @Override + public int available() throws IOException { + return 0; + } + + @Override + public int read(byte[] bytes, int i, int i1) { + return 0; + } + + @Override + public void close() throws IOException { + //close + } + }) { + // Fixed use on the device side192.168.10.1 + socket = new Socket(Const.IP, Const.CONFIG_PORT); + out = socket.getOutputStream(); + out.write(dataStr.getBytes("UTF-8")); + in = new BufferedReader(new InputStreamReader(socket.getInputStream())); + String str = in.readLine(); + LogUtil.info("configNet receive:", str); + return str; + } catch (IOException e) { + LogUtil.error(TAG, "", e); + LogUtil.error("configNet:", e.getMessage()); + return String.format("{\"code\":500, \"errmsg\":\"%s\"}", e.getMessage()); + } + } + + /** + * Initialize the device to monitor, + * send 0xff, 0x55, 0xaa, 0x55, 0x00 to tell the device to use this connection to feedback the status + * + * @param serverIp serverIp + */ + private void initDeviceListener(String serverIp) { + if (serverIp == null || "".equals(serverIp)) { + return; + } + try { + socketDeviceListener = new Socket(serverIp, Const.CONTROL_PORT); + OutputStream out = socketDeviceListener.getOutputStream(); + byte[] cmds = {(byte) NUMBER_FF, (byte) NUMBER_55, (byte) NUMBER_AA, (byte) NUMBER_55, (byte) NUMBER_00}; + out.write(cmds); + + BufferedReader in = new BufferedReader(new InputStreamReader(socketDeviceListener.getInputStream())); + Device Device = new Device(in); + Device.start(); + } catch (IOException e) { + LogUtil.error(TAG, "", e); + } + } + + /** + * Thread monitoring device report + * + * @since 2021-01-19 + */ + class Device extends Thread { + private BufferedReader input; + Device(BufferedReader in) { + this.input = in; + } + @Override + public void run() { + try { + while (true) { + String str = this.input.readLine(); + LogUtil.info("initDeviceListener controlDevice receive:", str); + if (controlStateRemoteObj != null) { + MessageParcel data = MessageParcel.obtain(); + MessageParcel reply = MessageParcel.obtain(); + MessageOption option = new MessageOption(); + data.writeString(ZSONObject.toZSONString(str)); + controlStateRemoteObj.sendRequest(NUMBER_100, data, reply, option); + } + } + } catch (IOException | RemoteException e) { + LogUtil.error("initDeviceListener controlDevice receive:", e.getMessage()); + } + } + } + +} \ No newline at end of file diff --git a/CompleteApps/SmartKettleApp/entry/src/main/java/ohos/samples/smartkettle/LogUtil.java b/CompleteApps/SmartKettleApp/entry/src/main/java/ohos/samples/smartkettle/LogUtil.java new file mode 100644 index 0000000000000000000000000000000000000000..4da77c6178c4035c38abbc3f8fda4a9deec47c90 --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/java/ohos/samples/smartkettle/LogUtil.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ohos.samples.smartkettle; + +import ohos.hiviewdfx.HiLog; +import ohos.hiviewdfx.HiLogLabel; + +import java.util.Locale; + +public class LogUtil { + private static final String TAG_LOG = ""; + + private static final int DOMAIN_ID = 0xD000F00; + + private static final HiLogLabel LABEL_LOG = new HiLogLabel(3, DOMAIN_ID, LogUtil.TAG_LOG); + + private static final String LOG_FORMAT = "%{public}s: %{public}s"; + + private static final boolean DEBUG = true; + + private LogUtil() { + } + + /** + * Print debug log + * + * @param tag log tag + * @param msg log message + */ + public static void debug(String tag, String msg) { + if (DEBUG) { + HiLog.debug(LABEL_LOG, LOG_FORMAT, tag, msg); + } + } + + /** + * Print info log + * + * @param tag log tag + * @param msg log message + */ + public static void info(String tag, String msg) { + if (DEBUG) { + HiLog.info(LABEL_LOG, LOG_FORMAT, tag, msg); + } + } + + /** + * Print warn log + * + * @param tag log tag + * @param msg log message + */ + public static void warn(String tag, String msg) { + if (DEBUG) { + HiLog.warn(LABEL_LOG, LOG_FORMAT, tag, msg); + } + } + + /** + * Print error log + * + * @param tag log tag + * @param msg log message + */ + public static void error(String tag, String msg) { + if (DEBUG) { + HiLog.error(LABEL_LOG, LOG_FORMAT, tag, msg); + } + + } + + public static void error(String tag, final String format, Object... args) { + if (DEBUG) { + String buffMsg = String.format(Locale.ROOT, format, args); + HiLog.error(LABEL_LOG, LOG_FORMAT, tag, buffMsg); + } + } + + public static void info(String tag, final String format, Object... args) { + if (DEBUG) { + String buffMsg = String.format(Locale.ROOT, format, args); + HiLog.info(LABEL_LOG, LOG_FORMAT, tag, buffMsg); + } + } +} diff --git a/CompleteApps/SmartKettleApp/entry/src/main/java/ohos/samples/smartkettle/MainAbility.java b/CompleteApps/SmartKettleApp/entry/src/main/java/ohos/samples/smartkettle/MainAbility.java new file mode 100644 index 0000000000000000000000000000000000000000..02212037ff649d3881c1dc6db9eb7c56dfee88f9 --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/java/ohos/samples/smartkettle/MainAbility.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ohos.samples.smartkettle; + +import ohos.aafwk.content.Intent; +import ohos.ace.ability.AceAbility; + +/** + * MainAbility + * + * @since 2021-01-19 + */ +public class MainAbility extends AceAbility { + + /** + * This is the default FeatureAbility entrance. + */ + @Override + public void onStart(Intent intent) { + // Start the current ability using half mode, 3 means pop-up mode when FeatureAbility start. + intent.setParam("window_modal", Const.THREE); + + // Start default FeatureAbility. + setInstanceName("default"); + this.requestPermissionsFromUser(new String[]{ohos.security.SystemPermission.LOCATION}, 0); + super.onStart( intent ); + } + + @Override + public void onStop() { + super.onStop(); + } +} diff --git a/CompleteApps/SmartKettleApp/entry/src/main/java/ohos/samples/smartkettle/MyApplication.java b/CompleteApps/SmartKettleApp/entry/src/main/java/ohos/samples/smartkettle/MyApplication.java new file mode 100644 index 0000000000000000000000000000000000000000..4690cfaf9a58567b0b298c665e6d5fd9b1c90089 --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/java/ohos/samples/smartkettle/MyApplication.java @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ohos.samples.smartkettle; + +import ohos.aafwk.ability.AbilityPackage; + +public class MyApplication extends AbilityPackage { + @Override + public void onInitialize() { + super.onInitialize(); + } +} diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/control/app.js b/CompleteApps/SmartKettleApp/entry/src/main/js/control/app.js new file mode 100644 index 0000000000000000000000000000000000000000..02323bed6e8810670605173d64beda15cc2a9192 --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/js/control/app.js @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export default { + onCreate() { + console.info('AceApplication onCreate'); + }, + onDestroy() { + console.info('AceApplication onDestroy'); + }, + onInit() { + }, + // The ServerIp after the device is successfully configured + ServerIp: '', + + AlarmList: [ + { + message: '', + hour: '08', + min: '00', + temp: '50', + state: 1 + }, + { + message: '', + hour: '13', + min: '30', + temp: '50', + state: 1 + }, + { + message: '', + hour: '16', + min: '00', + temp: '50', + state: 1 + }, + { + message: '', + hour: '18', + min: '00', + temp: '90', + state: 1 + } + ], + MessageList: [ + { + hour: '09', + min: '00', + state: 1 + }, + { + hour: '11', + min: '30', + state: 1 + }, + { + hour: '15', + min: '00', + state: 1 + }, + { + hour: '17', + min: '00', + state: 1 + } + ], + IntervalList: [ + { + hour: '09', + min: '00', + state: 1 + }, + ], + defModeValue: [ + { + textValue: '+', + tpValue: '', + }, + + { + textValue: '+', + tpValue: '' + }, + { + textValue: '+', + tpValue: '' + }, + { + textValue: '+', + tpValue: '' + }, + ], +}; diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/css/common.css b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/css/common.css new file mode 100644 index 0000000000000000000000000000000000000000..0fd571faa95451323aafe4365706560972f78996 --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/css/common.css @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +.flexcol { + flex-direction: column; +} +.flexrow { + flex-direction: row; +} +.jstart { + justify-content: flex-start; +} +.jcenter { + justify-content: center; +} +.jspacebe { + justify-content: space-between; +} +.jspacearound { + justify-content: space-around; +} +.astart { + align-items: flex-start; +} +.acenter { + align-items: center; +} +.color_black { + color: #000; +} +.color_gray { + color: #969ca1; +} +.color_white { + color: #fff; +} + +.color_yellow { + color: #ff9600; +} + +.text_black { + text-color: #000; +} +.color_blue { + color: #007dff; +} +.back_blue { + background-color: #007dff; +} +.back_color { + background-color: #f7f7f7; +} + +.back_white { + background-color: #fff; +} + +.back_yellow { + background-color: #ff9600; +} +.font25 { + font-size: 25px; +} +.font30 { + font-size: 30px; +} + +.font35 { + font-size: 35px; +} + +.font40 { + font-size: 40px; +} +.font45 { + font-size: 45px; +} +.font70 { + font-size: 70px; +} + +.mleft32 { + margin-left: 32px; +} + +.mright32 { + margin-right: 32px; +} +.mtop20 { + margin-top: 20px; +} + +.mbottom20 { + margin-bottom: 20px; +} +.mtop40 { + margin-top: 40px; +} + +.mbottom40 { + margin-bottom: 40px; +} + +.borradius16 { + border-radius: 16px; +} +.text_center { + align-content: center; + text-align: center; +} + +.flexux { + width: 720px; + height: 200px; + margin-bottom: 30px; + margin-top: 30px; +} +.modeux { + margin-left: 64px; +} + +.flexpart { + flex-direction: row; + justify-content: space-around; + align-items: center; +} + +.imageux { + width: 60px; + height: 60px; + margin-right: 20px; +} +.titleux { + margin-top: 20px; + margin-bottom: 30px; + color: #000; + font-size: 45px; +} +.saveux { + margin-top: 10px; + color: #007dff; + font-size: 35px; +} + +.circle { + margin-top: 20px; + margin-bottom: 20px; + background-color: #fff; + icon-width: 70px; + icon-height: 70px; + radius: 72px; +} +.dialogdiv { + flex-direction: column; + align-items: flex-start; + width: 625px; + height: 350px; +} + +.input { + width: 525px; + height: 100px; + margin-left: 50px; + margin-top: 10px; + margin-bottom: 10px; +} \ No newline at end of file diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/BG.png b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/BG.png new file mode 100644 index 0000000000000000000000000000000000000000..d2dd96f68f2d5e00f31f63c07d7fbe402fd50b96 Binary files /dev/null and b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/BG.png differ diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/ID_pic.png b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/ID_pic.png new file mode 100644 index 0000000000000000000000000000000000000000..f488f9adbaa27a1425b8b91b251b89de8c02bc0b Binary files /dev/null and b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/ID_pic.png differ diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/home_banner.png b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/home_banner.png new file mode 100644 index 0000000000000000000000000000000000000000..fca20b16675af33f169e667c358bd70d5c9ab365 Binary files /dev/null and b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/home_banner.png differ diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_coffee_off.png b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_coffee_off.png new file mode 100644 index 0000000000000000000000000000000000000000..4dcf71ba67b8bb0b20698defc320382b181a69c0 Binary files /dev/null and b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_coffee_off.png differ diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_coffee_selected.png b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_coffee_selected.png new file mode 100644 index 0000000000000000000000000000000000000000..725aa889ef7d728b203de5a50afca79e202eb972 Binary files /dev/null and b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_coffee_selected.png differ diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_coffee_unselected.png b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_coffee_unselected.png new file mode 100644 index 0000000000000000000000000000000000000000..cdbcc82696f4a7dc88b0cce8320710453b4f4333 Binary files /dev/null and b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_coffee_unselected.png differ diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_increase.png b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_increase.png new file mode 100644 index 0000000000000000000000000000000000000000..b548f108645d5b6feb628ea2b4645cdf770c03a4 Binary files /dev/null and b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_increase.png differ diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_milk_off.png b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_milk_off.png new file mode 100644 index 0000000000000000000000000000000000000000..d03fa7e2bae8b17b4571595a23ae6402ec3e9ce8 Binary files /dev/null and b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_milk_off.png differ diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_milk_selected.png b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_milk_selected.png new file mode 100644 index 0000000000000000000000000000000000000000..ead98d86476c984f15b04e6ae9167f8c23b36e1d Binary files /dev/null and b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_milk_selected.png differ diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_milk_unselected.png b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_milk_unselected.png new file mode 100644 index 0000000000000000000000000000000000000000..5f3707285beeea6807341f8e13bfb7f20f55ecad Binary files /dev/null and b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_milk_unselected.png differ diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_tea_off.png b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_tea_off.png new file mode 100644 index 0000000000000000000000000000000000000000..eb21df3f021b20fca0b121234cce27c2a153130b Binary files /dev/null and b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_tea_off.png differ diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_tea_selected.png b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_tea_selected.png new file mode 100644 index 0000000000000000000000000000000000000000..4c8756de7c6ed8e3aa7faf89d9971b4bab29fec9 Binary files /dev/null and b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_tea_selected.png differ diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_tea_unselected.png b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_tea_unselected.png new file mode 100644 index 0000000000000000000000000000000000000000..5f49851719d7625bf6bc148cec5a9380b8c9d143 Binary files /dev/null and b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_tea_unselected.png differ diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_timing_task.png b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_timing_task.png new file mode 100644 index 0000000000000000000000000000000000000000..5d96c0dfad695d58c006bbd9810729aaacc04f2f Binary files /dev/null and b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_timing_task.png differ diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_water_off.png b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_water_off.png new file mode 100644 index 0000000000000000000000000000000000000000..830e926aa1654a634f1f1a1341e0a2111736c880 Binary files /dev/null and b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_water_off.png differ diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_water_selected.png b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_water_selected.png new file mode 100644 index 0000000000000000000000000000000000000000..b1349dbbb4ebf526987f33f523445e371114ff7c Binary files /dev/null and b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_water_selected.png differ diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_water_unselected.png b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_water_unselected.png new file mode 100644 index 0000000000000000000000000000000000000000..b152bc4e8183481564c6408c45cf6709b73c910a Binary files /dev/null and b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_water_unselected.png differ diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/ic_power_off.png b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/ic_power_off.png new file mode 100644 index 0000000000000000000000000000000000000000..d2455f80e26f40883b7130e61333769d5cc20778 Binary files /dev/null and b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/ic_power_off.png differ diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/ic_power_on.png b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/ic_power_on.png new file mode 100644 index 0000000000000000000000000000000000000000..570a578448e37d74569458eb9bf9fa1fe193f157 Binary files /dev/null and b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/ic_power_on.png differ diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/icon_alarm_clock.png b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/icon_alarm_clock.png new file mode 100644 index 0000000000000000000000000000000000000000..3e1e3cd4035e07b70eb09ed39e8f104c51b4a3af Binary files /dev/null and b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/icon_alarm_clock.png differ diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/icon_back.png b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/icon_back.png new file mode 100644 index 0000000000000000000000000000000000000000..5f0c565c85816201c27be59d36071773cb0f4b43 Binary files /dev/null and b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/icon_back.png differ diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/icon_back_white.png b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/icon_back_white.png new file mode 100644 index 0000000000000000000000000000000000000000..4f07888fb6d0b1fd72b445d0312e8db4acf15837 Binary files /dev/null and b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/icon_back_white.png differ diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/icon_plus.png b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/icon_plus.png new file mode 100644 index 0000000000000000000000000000000000000000..3bea9cb29852d10cc591f4d4b8d649168fddb420 Binary files /dev/null and b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/icon_plus.png differ diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/icon_toward.png b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/icon_toward.png new file mode 100644 index 0000000000000000000000000000000000000000..be2d79e6456fcadf3ec763b3cfc565a6be857910 Binary files /dev/null and b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/icon_toward.png differ diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/icon_water_clock.png b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/icon_water_clock.png new file mode 100644 index 0000000000000000000000000000000000000000..1be7c1549102f9191c8c16dc1f0f4e2efcb6d8cb Binary files /dev/null and b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/icon_water_clock.png differ diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/net_success.png b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/net_success.png new file mode 100644 index 0000000000000000000000000000000000000000..46f28eee6ef36cde7043e784e2c984e0575d9ff9 Binary files /dev/null and b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/net_success.png differ diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/start_notice.png b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/start_notice.png new file mode 100644 index 0000000000000000000000000000000000000000..0ba364e33f7760e153cef273338572127b4d6f5f Binary files /dev/null and b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/start_notice.png differ diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/water notice _icon_turn.png b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/water notice _icon_turn.png new file mode 100644 index 0000000000000000000000000000000000000000..94643ba39483933f0bb7086fa4230d8712a0f909 Binary files /dev/null and b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/water notice _icon_turn.png differ diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/water_notice.png b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/water_notice.png new file mode 100644 index 0000000000000000000000000000000000000000..64a5e5efb8718542ed06b62a4e22add5be06ddc1 Binary files /dev/null and b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/img/water_notice.png differ diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/pages/header/header.css b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/pages/header/header.css new file mode 100644 index 0000000000000000000000000000000000000000..32ff9bf9f0e12d5c435f116655a259429647371d --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/pages/header/header.css @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@import '../../css/common.css'; +.device_img { + width: 304px; + height: 304px; +} + +.device_img_fullWindow { + width: 356px; + height: 356px; +} + +.mleft10{ + margin-left: 10px; +} + +.mtop10{ + margin-top: 10px; +} + +.marginother{ + margin-top: 0; +} +.icon{ + width: 50px; + height: 50px; +} \ No newline at end of file diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/pages/header/header.hml b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/pages/header/header.hml new file mode 100644 index 0000000000000000000000000000000000000000..f27ae3bd22bf7dea5843e79ea6f1b93e97a6a171 --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/pages/header/header.hml @@ -0,0 +1,37 @@ + + +
+
+
+ +
+ {{device_name}} + +
+ {{text_icon}} +
+
+ + {{neting_value}} + +
+
+ + {{success_value}} + +
+
+
\ No newline at end of file diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/pages/header/header.js b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/pages/header/header.js new file mode 100644 index 0000000000000000000000000000000000000000..59d93c0a712c76f5b2f68e879d73035ccefadbf4 --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/pages/header/header.js @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import app from '@system.app'; +export default{ + props: [ + 'device_name', + 'device_icon', + 'is_full', + 'os_icon', + 'text_icon', + 'home_icon', + + 'neting_state', + 'neting_value', + 'success_state', + 'success_icon', + 'success_value', + ], +}; diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/pages/setting/setting.css b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/pages/setting/setting.css new file mode 100644 index 0000000000000000000000000000000000000000..ace4cdbc14ce2a3f3db52ed173e67e7122e3ea93 --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/pages/setting/setting.css @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +@import '../../css/common.css'; + + diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/pages/setting/setting.hml b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/pages/setting/setting.hml new file mode 100644 index 0000000000000000000000000000000000000000..4c0f7849012dc103e0a1ddfb7551b7cc20295644 --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/pages/setting/setting.hml @@ -0,0 +1,21 @@ + + +
+
+ + {{title_text}} +
+
\ No newline at end of file diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/pages/setting/setting.js b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/pages/setting/setting.js new file mode 100644 index 0000000000000000000000000000000000000000..82e249032f061079676abf069ad7a8bf901e6f86 --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/pages/setting/setting.js @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import app from '@system.app'; +export default { + props: [ + 'back_src', + 'title_text', + + ], + returnBack() { + app.terminate(); + } +}; \ No newline at end of file diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/pages/title/title.css b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/pages/title/title.css new file mode 100644 index 0000000000000000000000000000000000000000..5f1564939288b49198d10d8558b6401e2f7a0f60 --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/pages/title/title.css @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +@import '../../css/common.css'; \ No newline at end of file diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/pages/title/title.hml b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/pages/title/title.hml new file mode 100644 index 0000000000000000000000000000000000000000..84fb286b95c50f8f55bbbdc5c1b0641ccc0e0a1a --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/pages/title/title.hml @@ -0,0 +1,22 @@ + + +
+
+ + {{title_text}} + {{save_text}} +
+
\ No newline at end of file diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/pages/title/title.js b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/pages/title/title.js new file mode 100644 index 0000000000000000000000000000000000000000..4eba89998cd9cbe1d23317de98c61f1744d75f5a --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/js/control/common/pages/title/title.js @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import app from '@system.app'; +import router from '@system.router'; +export default { + props: [ + 'img_src', + 'title_text', + 'save_text', + 'save' + ], + returnBack() { + router.back(); + }, +}; \ No newline at end of file diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/control/i18n/en-US.json b/CompleteApps/SmartKettleApp/entry/src/main/js/control/i18n/en-US.json new file mode 100644 index 0000000000000000000000000000000000000000..3c0e6762221bc8898cd535284e03e09cdd504c48 --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/js/control/i18n/en-US.json @@ -0,0 +1,91 @@ +{ + "strings": { + "deviceName": "SmartKettle", + "logoName": "CPlogo", + "netingValue": "DistributionNetworkIsInProgress..", + "successValue": "DistributionNetworkSuccess", + "holdingTemperature": "HoldingTemperature", + "25temperature": "25℃", + "50temperature": "50℃", + "80temperature": "80℃", + "99temperature": "99℃", + "warmWater": "Drinking", + "milk":"Milk", + "tea": "Tea", + "boilingWater": "Boiled", + "holdingTime": "KeepTime", + "keepWarm": "AutoKeep", + "more": "More", + "down": "BoilToHoldingTemperature", + "up": "HeatingToHoldingTemperature", + "autoSet": "AutomationSettings", + "ServiceRecommond": "ServiceRecommendation", + "setted": "YouSet“", + "running": "“StartRunning", + "tips": "EnterAName(NoMoreThan6Words)", + "alarmClock": "SetScheduledTasks", + "waterClock": "SetWaterReminder", + "setName": "EnterName", + "100temperature": "100℃", + "warm": "ACupOfWarmWaterInTheMorning", + "feeding": "GiveTheBreastToOne'sBaby", + "afternoonTea":"BeautyAfternoonTea", + "gingerTea": "BrownSugarGingerTea", + "noMore24": "CannotExceed24,SetTo00", + "noMore60": "CannotExceed60,SetTo00", + "noMore100": "CannotExceed100,SetTo100", + "startTime": "StartTime", + "endTime": "EndTime", + "opened": "On", + "closed": "Off", + "drinkWater": "It'sTimeToDrink", + "waterBoiled": "~~Master,TheWaterIsBoiling~~", + "heating": "Heating", + "keepingWarm": "Keeping", + "failedAccept": "FailedToAcceptMessage", + "failedSend": "FailedToSendMessage", + "timedTask":"TimedTask", + "logging":"Logging", + "dailyExecution": "DailyExecution", + "input": "PleaseEnter...", + "hour": "Hour", + "minute":"Minute", + "temperature": "Temperature", + "cancle":"Cancel", + "buttonOk": "Determine", + "repairservice": "MaintenanceService", + "service": "PersonalService", + "amount": "¥100", + "serviceTime": "Time", + "time": "Wednesday", + "contact": "ContactTheMerchant", + "buyNow": "BuyNow", + "drinkReminder": "WaterClock", + "save": "Save", + "modeSelect": "ModeSelection", + "timing": "Timing", + "interval": "Interval", + "setTime": "SetTimePoint", + "edit": "Edit", + "IntervalLength": "IntervalDuration", + "hours": "h", + "12hours": "12h" + + }, + "files": { + "backSrc": "/common/img/icon_back.png", + "deviceIcon": "/common/img/ID_pic.png", + "successIcon": "/common/img/net_success.png", + "homeBanner": "/common/img/home_banner.png", + "timingTask": "/common/img/home_icon_timing_task.png", + "iconAlarm": "/common/img/icon_alarm_clock.png", + "iconWater": "/common/img/icon_water_clock.png", + "startNotice": "/common/img/start_notice.png", + "waterNotice": "/common/img/water_notice.png", + "iconSrc": "common/img/icon_plus.png", + "serviceBack": "/common/img/BG.png", + "returnImg": "/common/img/icon_back_white.png", + "towardImg":"/common/img/icon_toward.png", + "turnOnImg": "/common/img/water notice _icon_turn.png" + } +} diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/control/i18n/zh-CN.json b/CompleteApps/SmartKettleApp/entry/src/main/js/control/i18n/zh-CN.json new file mode 100644 index 0000000000000000000000000000000000000000..956803ddc594d7a94dba7df7a6d4895ef63e4c0c --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/js/control/i18n/zh-CN.json @@ -0,0 +1,91 @@ +{ + "strings": { + "deviceName": "智能恒温水壶", + "logoName": "CPlogo", + "netingValue": "正在配网,您可以进行部分控制", + "successValue": "配网成功", + "holdingTemperature": "保温温度", + "25temperature": "25℃", + "50temperature": "50℃", + "80temperature": "80℃", + "99temperature": "99℃", + "warmWater": "直饮", + "milk":"冲奶", + "tea": "茶饮", + "boilingWater": "开水", + "holdingTime": "保温时长", + "keepWarm": "自动保温", + "more": "查看更多", + "down": "煮沸降至保温温度", + "up": "加热升至保温温度", + "autoSet": "自动化设置", + "ServiceRecommond": "服务推荐", + "setted": "您设定的“", + "running": "“开始运行", + "tips": "输入名称(不超过6个字)", + "alarmClock": "设置定时任务", + "waterClock": "设置喝水提醒", + "setName": "输入名称", + "100temperature": "100℃", + "warm": "早上一杯温水", + "feeding": "给孩子喂奶", + "afternoonTea":"养颜下午茶", + "gingerTea": "红糖姜茶", + "noMore24": "不能超过24,设置为00", + "noMore60": "不能超过60.设置为00", + "noMore100": "不能超过100.设置为100", + "startTime": "开始时间", + "endTime": "结束时间", + "opened": "已开启", + "closed": "已关闭", + "drinkWater": "主人到了喝水时间了", + "waterBoiled": "~~主人,水烧开了~~", + "heating": "加热中", + "keepingWarm": "保温中", + "failedAccept": "接受消息失败", + "failedSend": "发送消息失败", + "timedTask":"定时任务", + "logging":"日志记录", + "dailyExecution": "每天 执行", + "input": "请输入...", + "hour": "时", + "minute":"分", + "temperature": "温度", + "cancle":"取消", + "buttonOk": "确定", + "repairservice": "上门维修服务", + "service": "上门维修,贴身服务", + "amount": "¥100", + "serviceTime": "服务时间", + "time": "周三14:00", + "contact": "联系商家", + "buyNow": "立即购买", + "drinkReminder": "喝水提醒", + "save": "保存", + "modeSelect": "模式选择", + "timing": "定时", + "interval": "间隔", + "setTime": "设置时间点", + "edit": "编辑", + "IntervalLength": "间隔时长", + "hours": "h", + "12hours": "12h" + + }, + "files": { + "backSrc": "/common/img/icon_back.png", + "deviceIcon": "/common/img/ID_pic.png", + "successIcon": "/common/img/net_success.png", + "homeBanner": "/common/img/home_banner.png", + "timingTask": "/common/img/home_icon_timing_task.png", + "iconAlarm": "/common/img/icon_alarm_clock.png", + "iconWater": "/common/img/icon_water_clock.png", + "startNotice": "/common/img/start_notice.png", + "waterNotice": "/common/img/water_notice.png", + "iconSrc": "common/img/icon_plus.png", + "serviceBack": "/common/img/BG.png", + "returnImg": "/common/img/icon_back_white.png", + "towardImg":"/common/img/icon_toward.png", + "turnOnImg": "/common/img/water notice _icon_turn.png" + } +} \ No newline at end of file diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/control/pages/device/index.css b/CompleteApps/SmartKettleApp/entry/src/main/js/control/pages/device/index.css new file mode 100644 index 0000000000000000000000000000000000000000..80b0b5f171bf0765d99bf22229959a006e7eae90 --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/js/control/pages/device/index.css @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@import '../../common/css/common.css'; + + +.w192h192 { + width: 192px; + height: 192px; +} + +.w55h55 { + width: 55px; + height: 55px; +} + +.mbottom10 { + width: 155px; + height: 110px; + margin-bottom: 10px; +} + +.mbottom4 { + width: 200px; + margin-bottom: 4px; + +} +.padding40 { + width: 320px; + height: 120px; + padding: 40px 40px 40px 40px; +} + diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/control/pages/device/index.hml b/CompleteApps/SmartKettleApp/entry/src/main/js/control/pages/device/index.hml new file mode 100644 index 0000000000000000000000000000000000000000..8b4a3284ec0fd9ea5b914ddffb9ca85b44e2ad28 --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/js/control/pages/device/index.hml @@ -0,0 +1,195 @@ + + + + +
+ +
+ + +
+ {{SwitchValue}} +
+ {{TempNumber}}℃ + {{TempState}} +
+ +
+
+ + + {{$t('strings.holdingTemperature')}} +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+ {{$t('strings.25temperature')}} +
+
+ {{$t('strings.50temperature')}} +
+
+ {{$t('strings.80temperature')}} +
+
+ {{$t('strings.99temperature')}} +
+
+
+
+ {{$t('strings.warmWater')}} +
+
+ {{$t('strings.milk')}} +
+
+ {{$t('strings.tea')}} +
+
+ {{$t('strings.boilingWater')}} +
+
+ + +
+
+ {{$item.textvalue}} +
+
+
+
+ {{$item.tpvalue}} +
+
+ + +
+ + {{$t('strings.100temperature')}} +
+ {{temp}}℃ + + +
+ {{$t('strings.holdingTime')}} + {{$t('strings.keepWarm')}} + +
+ + +
+ + {{$t('strings.12hours')}} +
+ {{capacity}}h +
+ +
+
+ +
+ {{$t('strings.more')}} +
+ + +
+
+ + +
+ {{$t('strings.autoSet')}} +
+
+ + {{$t('strings.alarmClock')}} + +
+
+
+
+ + {{$t('strings.waterClock')}} + +
+
+ {{$t('strings.ServiceRecommond')}} + +
+ + + +
+
+ +
+ {{$t('strings.setted')}} {{TextMessage}} {{$t('strings.running')}} +
+ + +
+
+
+ + + +
+
+ +
+ {{DrinkTime}} +
+ + +
+
+
+ + + +
+
+ {{$t('strings.setName')}} + +
+
+ {{$t('strings.temperature')}} + + {{temperature}}℃ +
+
+ + +
+
+
+
\ No newline at end of file diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/control/pages/device/index.js b/CompleteApps/SmartKettleApp/entry/src/main/js/control/pages/device/index.js new file mode 100644 index 0000000000000000000000000000000000000000..0752859e5436b48ed90335fddc91229006090a95 --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/js/control/pages/device/index.js @@ -0,0 +1,602 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import router from '@system.router'; +import prompt from '@system.prompt'; +import app from '@system.app'; + +var faSoftapUtil = require('fa-softaputil'); +var fanConstants = require('fan-constants'); + +export default { + data: { + IsFullWindow: false, + MoreVisible: false, + NetState: true, + SuccessFlag: false, + SwitchValue: '', + isSubscribeControlState: false, + SwitchImg: '/common/img/ic_power_off.png', + SwitchState: 0, + TempNumber: '50', + TempState: '', + IconCoffee: '/common/img/home_icon_coffee_off.png', + IconMilk: '/common/img/home_icon_milk_off.png', + IconTea: '/common/img/home_icon_tea_off.png', + IconWater: '/common/img/home_icon_water_off.png', + WarmWaterColor: '#9B9B9B', + MilkColor: '#9B9B9B', + TeaColor: '#9B9B9B', + BoiledWaterColor: '#9B9B9B', + BoiledColor: '#ff9600', + WarmColor: '#ffffff', + TextBoiledColor: '#ffffff', + TextWarmColor: '#000000', + DefModeValue: [ + { + textvalue: '+', + tpvalue: '', + backcolor: '#9B9B9B' + }, + + { + textvalue: '+', + tpvalue: '', + backcolor: '#9B9B9B' + }, + { + textvalue: '+', + tpvalue: '', + backcolor: '#9B9B9B' + }, + { + textvalue: '+', + tpvalue: '', + backcolor: '#9B9B9B' + }, + ], + TextMessage: '', + DrinkTime: '', + state: 1, + temp: 25, + capacity: 8, + type: '', + name: 'boiled', + message: '', + date: '', + hour: '', + minute: '', + SetName: ' ', + temperature: 25, + ShowFlag: 0, + AddIndex: 0, + toast: { + SendFailed: '', + RecvFailed: '', + close: '', + }, + serverIp: '' + }, + +/** + * Get transmission connection sessionid + * Call checkTime once a second + * + */ + onInit() { + this.SwitchValue = this.$t('strings.closed'); + this.TempState = this.$t('strings.keepingWarm'); + + this.toast.RecvFailed = this.$t('strings.failedAccept'); + this.toast.close = this.$t('strings.closed'); + this.toast.SendFailed = this.$t('strings.failedSend'); + + // Successful network ServerIp + this.$app.$def.ServerIp = this.dataInfo; + this.serverIp = this.$app.$def.ServerIp; + + let time = setInterval(() => { + this.checkTime(); + }, 1000); //Delay 1 seconds + }, + +// Show net state + onShow() { + if (this.ShowFlag === 0) { + let timeoutID1 = setTimeout(() => { + + this.NetState = false; + this.SuccessFlag = true; + }, 3000); // Delay 3 seconds + + let timeoutID2 = setTimeout(() => { + + this.NetState = false; + this.SuccessFlag = false; + }, 5000); // Delay 5 seconds + this.ShowFlag = 1; + + // Send a message to the device after entering the control page + this.sendControlMessage(); + } + }, + +// Show more components + getMoreClick() { + if (this.IsFullWindow) { + this.IsFullWindow = false; + } else { + this.IsFullWindow = true; + + // Change half mode to full mode + app.requestFullWindow(); + } + }, + +/** + * Timed reminder message detection + * After the time is up, a pop-up reminder + * + */ + checkTime() { + this.date = new Date(); + this.hour = this.date.getHours(); + this.minute = this.date.getMinutes(); + for (let index = 0; index < this.$app.$def.AlarmList.length; index++) { + if (this.$app.$def.AlarmList[index].state === 1) { + if ((this.hour === this.$app.$def.AlarmList[index].hour) && + (this.minute === this.$app.$def.AlarmList[index].min)) { + this.addSchedule(); + this.$app.$def.AlarmList[index].state = 0; + this.TextMessage = this.$app.$def.AlarmList[index].message; + this.temp = this.$app.$def.AlarmList[index].temp; + this.type = this.$app.$def.AlarmList[index].message; + this.sendControlMessage(); + } + } + } + for (let index = 0; index < this.$app.$def.MessageList.length; index++) { + if (this.$app.$def.MessageList[index].state === 1) { + if ((this.hour === this.$app.$def.MessageList[index].hour) && + (this.minute == this.$app.$def.MessageList[index].min)) { + this.DrinkTime = this.$t('strings.drinkWater'); + this.addScheduleTip(); + this.$app.$def.MessageList[index].state = 0; + } + } + } + for (let index = 0; index < this.$app.$def.IntervalList.length; index++) { + if (this.$app.$def.IntervalList[index].state === 1) { + if ((this.hour === this.$app.$def.IntervalList[index].hour) && + (this.minute === this.$app.$def.IntervalList[index].min)) { + this.DrinkTime = this.$t('strings.drinkWater'); + this.addScheduleTip(); + this.$app.$def.IntervalList[index].state = 0; + } + } + } + }, + +/** + * Register message accept callback function + * Receive and process device-side messages + * + */ + onReady: async function onReady() { + this.initSubscribeControlState(); + }, + +// Monitor device response + initSubscribeControlState() { + if (this.isSubscribeControlState === false) { + let that = this; + faSoftapUtil.FASoftapUtil.subscribe(fanConstants.CONSTANTS.SUBSCRIBE_CONTROL_STATE, function (callbackData) { + var callbackJson = JSON.parse(callbackData); + var event = callbackJson.data; + if (event === 'time') { + that.DrinkTime = that.$t('strings.waterBoiled'); + that.addScheduleTip(); + } + else { + var n = event.split(' '); + that.TempNumber = n[0]; + if (n[1].includes('1')) { + that.TempState = that.$t('strings.heating'); + } + else { + that.TempState = that.$t('strings.keepingWarm'); + } + } + that.isSubscribeControlState = true; + }); + } + }, +// Goto service page + gotoFlex() { + router.push({ + uri: 'pages/service/index' + }); + }, + +// Close datedialog. + cancelSchedule() { + this.$element('datedialog').close(); + }, + +// Close datedialog_tip. + cancelScheduleTip() { + this.$element('datedialog_tip').close(); + }, + +// Close datedialog_input. + cancelScheduleInput() { + this.$element('datedialog_input').close(); + }, + + +// Show datedialog. + addSchedule() { + this.$element('datedialog').show(); + }, + +// Show datedialog_tip. + addScheduleTip() { + this.$element('datedialog_tip').show(); + }, + +// Show datedialog_input. + addScheduleInput() { + this.$element('datedialog_input').close(); + + this.$app.$def.defModeValue[this.AddIndex].textValue = this.SetName; + this.$app.$def.defModeValue[this.AddIndex].tpValue = this.temperature + '℃'; + this.DefModeValue[this.AddIndex].textvalue = this.$app.$def.defModeValue[this.AddIndex].textValue; + this.DefModeValue[this.AddIndex].tpvalue = this.$app.$def.defModeValue[this.AddIndex].tpValue; + }, + +/** + * select warmWater mode + * + * + */ + warmWater() { + if (this.SwitchState === 1) { + this.temp = 25; // temperature is 25 + this.type = this.$t('strings.warmWater'); + + this.IconCoffee = '/common/img/home_icon_coffee_selected.png'; + this.IconMilk = '/common/img/home_icon_milk_unselected.png'; + this.IconTea = '/common/img/home_icon_tea_unselected.png'; + this.IconWater = '/common/img/home_icon_water_unselected.png'; + + this.WarmWaterColor = '#487Bfd'; + this.MilkColor = '#000000'; + this.TeaColor = '#000000'; + this.BoiledWaterColor = '#000000'; + + for (let i = 0; i < this.DefModeValue.length; i++) { + this.DefModeValue[i].backcolor = '#000000'; + } + + } + else { + prompt.showToast({ + message: this.toast.close + }); + } + }, + +/** + * select milk mode + * + * + */ + milk() { + if (this.SwitchState === 1) { + this.temp = 50; // temperature is 50 + this.type = this.$t('strings.milk'); + + this.IconCoffee = '/common/img/home_icon_coffee_unselected.png'; + this.IconMilk = '/common/img/home_icon_milk_selected.png'; + this.IconTea = '/common/img/home_icon_tea_unselected.png'; + this.IconWater = '/common/img/home_icon_water_unselected.png'; + + this.WarmWaterColor = '#000000'; + this.MilkColor = '#487Bfd'; + this.TeaColor = '#000000'; + this.BoiledWaterColor = '#000000'; + + for (let i = 0; i < this.DefModeValue.length; i++) { + this.DefModeValue[i].backcolor = '#000000'; + } + + } + else { + prompt.showToast({ + message: this.toast.close + }); + } + }, + +/** + * select tea mode + * + * + */ + tea() { + if (this.SwitchState === 1) { + this.temp = 80; // temperature is 80 + this.type = this.$t('strings.tea'); + + this.IconCoffee = '/common/img/home_icon_coffee_unselected.png'; + this.IconMilk = '/common/img/home_icon_milk_unselected.png'; + this.IconTea = '/common/img/home_icon_tea_selected.png'; + this.IconWater = '/common/img/home_icon_water_unselected.png'; + + this.WarmWaterColor = '#000000'; + this.MilkColor = '#000000'; + this.TeaColor = '#487Bfd'; + this.BoiledWaterColor = '#000000'; + + for (let i = 0; i < this.DefModeValue.length; i++) { + this.DefModeValue[i].backcolor = '#000000'; + } + + } + else { + prompt.showToast({ + message: this.toast.close + }); + } + }, + +/** + * select boilingWater mode + * + * + */ + water() { + if (this.SwitchState === 1) { + this.temp = 99; // temperature is 99 + this.type = this.$t('strings.boilingWater'); + + this.IconCoffee = '/common/img/home_icon_coffee_unselected.png'; + this.IconMilk = '/common/img/home_icon_milk_unselected.png'; + this.IconTea = '/common/img/home_icon_tea_unselected.png'; + this.IconWater = '/common/img/home_icon_water_selected.png'; + + this.WarmWaterColor = '#000000'; + this.MilkColor = '#000000'; + this.TeaColor = '#000000'; + this.BoiledWaterColor = '#487Bfd'; + + for (let i = 0; i < this.DefModeValue.length; i++) { + this.DefModeValue[i].backcolor = '#000000'; + } + + } + else { + prompt.showToast({ + message: this.toast.close + }); + } + }, + +/** + * Add custom mode or select this mode + * + * + */ + add(index) { + if (this.SwitchState === 1) { + if (this.DefModeValue[index].textvalue === '+') { + this.AddIndex = index; + this.$element('datedialog_input').show(); + } + else { + this.temp = this.DefModeValue[index].tpvalue.replace('℃', ''); + this.type = this.DefModeValue[index].textvalue; + + this.IconCoffee = '/common/img/home_icon_coffee_unselected.png'; + this.IconMilk = '/common/img/home_icon_milk_unselected.png'; + this.IconTea = '/common/img/home_icon_tea_unselected.png'; + this.IconWater = '/common/img/home_icon_water_unselected.png'; + + this.WarmWaterColor = '#000000'; + this.MilkColor = '#000000'; + this.TeaColor = '#000000'; + this.BoiledWaterColor = '#000000'; + + for (let i = 0; i < this.DefModeValue.length; i++) { + this.DefModeValue[i].backcolor = '#000000'; + } + this.DefModeValue[index].backcolor = '#487Bfd'; + + } + } + else { + prompt.showToast({ + message: this.toast.close + }); + } + }, + +/** + * Send boiled messages + * + * + */ + sendMessageBoiled() { + this.BoiledColor = '#ff9600'; + this.WarmColor = '#ffffff'; + this.TextBoiledColor = '#ffffff'; + this.TextWarmColor = '#000000'; + + // Boil down to keep warm + this.name = 'boiled'; + this.sendControlMessage(); + }, + +/** + * Send warm messages + * + * + */ + sendMessageWarm() { + this.BoiledColor = '#ffffff'; + this.WarmColor = '#487bfd'; + this.TextBoiledColor = '#000000'; + this.TextWarmColor = '#ffffff'; + + // Heat up to keep warm + this.name = 'warm'; + this.sendControlMessage(); + }, + +/** + * Goto timer page + * + * + */ + timerPage() { + router.push({ + uri: 'pages/timer/index' + }); + }, + +/** + * Goto reminder page + * + * + */ + reminderPage() { + router.push({ + uri: 'pages/reminder/index' + }); + }, + +/** + * Set temp + * + * @param e e + */ + setTemp(e) { + this.temp = Number(e.progress); + }, + +/** + * Set capacity + * + * @param e e + */ + setCapacity(e) { + this.capacity = Number(e.progress); + }, + +/** + * Set SetName + * + * @param e e + */ + setName(e) { + this.SetName = e.text; + }, + +/** + * Set temperature + * + * @param e e + */ + setTemperature(e) { + this.temperature = Number(e.progress); + }, + +// Call the interface to send protocol messages to the device + sendControlMessage() { + let data = {}; + data.serverIp = this.serverIp; + if (this.state === 0) { + this.message = this.name + ' ' + this.temp + ' ' + '0' + ' ' + this.type; + } + else { + this.message = this.name + ' ' + this.temp + ' ' + this.capacity + ' ' + this.type; + } + data.message = this.message; + faSoftapUtil.FASoftapUtil.sendMessage(data, fanConstants.CONSTANTS.CONTROL_CODE); + }, + +/** + * Auto keep warm switch control fuction + * @param e e + * + */ + switchChange(e) { + if (e.checked) { + this.state = 1; + } else { + this.state = 0; + } + }, + +/** + * + * Switch control function and set the page component properties + * + */ + powerChange() { + if (this.SwitchState === 0) { + + this.SwitchImg = '/common/img/ic_power_on.png'; + this.SwitchValue = this.$t('strings.opened'); + this.SwitchState = 1; + + this.IconCoffee = '/common/img/home_icon_coffee_unselected.png'; + this.IconMilk = '/common/img/home_icon_milk_unselected.png'; + this.IconTea = '/common/img/home_icon_tea_unselected.png'; + this.IconWater = '/common/img/home_icon_water_unselected.png'; + + this.WarmWaterColor = '#000000'; + this.MilkColor = '#000000'; + this.TeaColor = '#000000'; + this.BoiledWaterColor = '#000000'; + + for (let i = 0; i < this.DefModeValue.length; i++) { + this.DefModeValue[i].backcolor = '#000000'; + } + + } + else { + + this.SwitchImg = '/common/img/ic_power_off.png' + this.SwitchValue = this.$t('strings.closed'); + this.SwitchState = 0; + + this.IconCoffee = '/common/img/home_icon_coffee_off.png'; + this.IconMilk = '/common/img/home_icon_milk_off.png'; + this.IconTea = '/common/img/home_icon_tea_off.png'; + this.IconWater = '/common/img/home_icon_water_off.png'; + + this.WarmWaterColor = '#9B9B9B'; + this.MilkColor = '#9B9B9B'; + this.TeaColor = '#9B9B9B'; + this.BoiledWaterColor = '#9B9B9B'; + + for (let i = 0; i < this.DefModeValue.length; i++) { + this.DefModeValue[i].backcolor = '#9B9B9B'; + } + + } + }, +}; diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/control/pages/interval/index.css b/CompleteApps/SmartKettleApp/entry/src/main/js/control/pages/interval/index.css new file mode 100644 index 0000000000000000000000000000000000000000..10d8d2b7c3cc2101a967d4947465aed6c89ee61a --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/js/control/pages/interval/index.css @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@import '../../common/css/common.css'; + +.solidux { + width: 720px; + height: 150px; + border-bottom-style: solid; + border-bottom-width: 2px; + border-bottom-color: #cfcfcf; +} + +.mleftright64 { + margin-left: 64px; + margin-right: 64px; +} + +.progressux { + color: #9b9b9b; + margin-top: 52px; + selected-color: #487bfd; + block-color: #487bfd; +} + +.progresstextux { + color: #cfcfcf; + width: 150px; + margin-top: 20px; +} + + + + + diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/control/pages/interval/index.hml b/CompleteApps/SmartKettleApp/entry/src/main/js/control/pages/interval/index.hml new file mode 100644 index 0000000000000000000000000000000000000000..9aa1ba24f9d158faf77fd21e801576e5c39990a0 --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/js/control/pages/interval/index.hml @@ -0,0 +1,56 @@ + + +
+
+ + {{$t('strings.drinkReminder')}} + {{$t('strings.save')}} +
+
+ {{$t('strings.modeSelect')}} +
+ + +
+
+
+
+ {{$item.text}} + {{$item.hour}}:{{$item.min}} + +
+
+ {{$t('strings.IntervalLength')}} + {{capacity}}{{$t('strings.hours')}} +
+
+ + {{$t('strings.12hours')}} +
+
+ +
+
+ + +
+
+ + +
+
+
+
\ No newline at end of file diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/control/pages/interval/index.js b/CompleteApps/SmartKettleApp/entry/src/main/js/control/pages/interval/index.js new file mode 100644 index 0000000000000000000000000000000000000000..3653556b11aab3b767440e24b87167757a7f9247 --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/js/control/pages/interval/index.js @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import router from '@system.router'; +import prompt from '@system.prompt'; + +export default { + data: { + hour: '', + min: '', + capacity: '3', + number: '', + IntervalList: [ + { + text: '', + hour: '09', + min: '00', + buttonsrc: '' + }, + { + text: '', + hour: '20', + min: '00', + buttonsrc: '' + }, + ], + toast: { + HourMessage: '', + MinMessage: '' + } + + }, + onInit() { + this.toast.HourMessage = this.$t('strings.noMore24'); + this.toast.MinMessage = this.$t('strings.noMore60'); + + this.IntervalList[0].text = this.$t('strings.startTime'); + this.IntervalList[1].text = this.$t('strings.endTime'); + this.IntervalList[0].buttonsrc = this.$t('files.turnOnImg'); + this.IntervalList[1].buttonsrc = this.$t('files.turnOnImg'); + }, + + /** + * Get input hour + * + * @param e e + */ + getHour(e) { + if (e.text > 23) { // 23 hours maximum + prompt.showToast({ + message: this.toast.HourMessage + }); + e.text = '00'; + } + this.hour = e.text; + }, + + /** + * Get input Minute + * + * @param e e + */ + getMin(e) { + if (e.text > 59) { // 59 minutes maximum + prompt.showToast({ + message: this.toast.MinMessage + }); + e.text = '00'; + } + this.min = e.text; + }, + + /** + * Push informations into IntervalList object. + * + * @param e e + */ + setSchedule() { + + // If it is less than 10, ten digits are supplemented by 0 + if (Number(this.hour) < 10) { + this.hour = '0' + this.hour; + } + // If it is less than 10, ten digits are supplemented by 0 + if (Number(this.min) < 10) { + this.min = '0' + this.min; + } + + this.IntervalList[this.number].hour = this.hour; + this.IntervalList[this.number].min = this.min; + + this.$element('datedialog').close(); + }, + + // Show dialog. + addSchedule(index) { + this.number = index; + this.$element('datedialog').show(); + }, + + // Close dialog. + cancelSchedule() { + this.$element('datedialog').close(); + }, + + /** + * Get input capacity + * + * @param e e + */ + + getCapacity(e) { + this.capacity = Number(e.progress); + }, + + // Back to the previous page. + returnBack() { + router.back(); + }, + + // Goto reminder page. + reminderPage() { + router.push({ + uri: 'pages/reminder/index' + }); + }, + + // Open send interval reminder switch + changeSwitch() { + let i = Number(this.IntervalList[1].hour) - Number(this.IntervalList[0].hour) / Number(this.capacity); + for (let j = 0; j < i; j++) { + let addItem = { + hour: Number(this.IntervalList[0]) + Number(this.capacity) * j, + min: Number(this.IntervalList[1].min) - Number(this.IntervalList[0].min), + state: 1, + }; + this.$app.$def.IntervalList.push(addItem); + } + router.back(); + } +}; diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/control/pages/reminder/index.css b/CompleteApps/SmartKettleApp/entry/src/main/js/control/pages/reminder/index.css new file mode 100644 index 0000000000000000000000000000000000000000..1d0b8dccadc0720da6fa2ee23f7f37053a2f2432 --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/js/control/pages/reminder/index.css @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@import '../../common/css/common.css'; +.solidux { + width: 720px; + height: 150px; + border-bottom-style: solid; + border-bottom-width: 2px; + border-bottom-color: #cfcfcf; +} + + diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/control/pages/reminder/index.hml b/CompleteApps/SmartKettleApp/entry/src/main/js/control/pages/reminder/index.hml new file mode 100644 index 0000000000000000000000000000000000000000..11a56541f693c6e4c00e17d5f9962f553fc6e05d --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/js/control/pages/reminder/index.hml @@ -0,0 +1,49 @@ + + + +
+ +
+ {{$t('strings.modeSelect')}} +
+ + +
+
+
+
+ {{$t('strings.setTime')}} + {{$t('strings.edit')}} +
+
+ {{$item.hour}}:{{$item.min}} + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
\ No newline at end of file diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/control/pages/reminder/index.js b/CompleteApps/SmartKettleApp/entry/src/main/js/control/pages/reminder/index.js new file mode 100644 index 0000000000000000000000000000000000000000..58b80fdd77ea0eed943297f9fcefca56e0f1a3be --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/js/control/pages/reminder/index.js @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import router from '@system.router'; +import prompt from '@system.prompt'; +export default { + data: { + hour: '', + min: '', + ScheduleList: [], + toast: { + HourMessage: '', + MinMessage: '' + } + + }, + onInit() { + this.toast.HourMessage = this.$t('strings.noMore24'); + this.toast.MinMessage = this.$t('strings.noMore60'); + this.ScheduleList = this.$app.$def.MessageList; + }, + + /** + * Get input hour + * + * @param e e + */ + getHour(e) { + if (e.text > 23) { // 23 hours maximum + prompt.showToast({ + message: this.toast.HourMessage + }); + e.text = '00'; + } + this.hour = e.text; + }, + + /** + * Get input Minute + * + * @param e e + */ + getMin(e) { + if (e.text > 59) { // 59 minutes maximum + prompt.showToast({ + message: this.toast.MinMessage + }); + e.text = '00'; + } + this.min = e.text; + }, + + /** + * Push informations into MessageList object. + * + * @param e e + */ + setSchedule(e) { + // If it is less than 10, ten digits are supplemented by 0 + if (Number(this.hour) < 10) { + this.hour = '0' + this.hour; + } + // If it is less than 10, ten digits are supplemented by 0 + if (Number(this.min) < 10) { + this.min = '0' + this.min; + } + let addItem = { + hour: this.hour, + min: this.min, + state: 1, + }; + this.$app.$def.MessageList.push(addItem); + this.$element('datedialog').close(); + }, + + // Show dialog. + addSchedule() { + this.$element('datedialog').show(); + }, + + // Close dialog. + cancelSchedule() { + this.$element('datedialog').close(); + }, + + // Change MessageList object state value. + switchChange(index, e) { + if (e.checked) { + this.$app.$def.MessageList[index].state = 1; + } else { + this.$app.$def.MessageList[index].state = 0; + } + }, + + // Delete one an AlarmList object. + deleteItem(index, e) { + this.$app.$def.MessageList.splice(index, 1); + }, + + // Goto interval page. + intervalPage() { + router.push({ + uri: 'pages/interval/index' + }); + } +}; diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/control/pages/service/index.css b/CompleteApps/SmartKettleApp/entry/src/main/js/control/pages/service/index.css new file mode 100644 index 0000000000000000000000000000000000000000..391baa32f50f71a395d3bf7b8131fbf860d1c229 --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/js/control/pages/service/index.css @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@import '../../common/css/common.css'; +.center { + width: 100%; + height: 514px; +} + +.imageux { + width: 55px; + height: 55px; +} + +.between { + width: 654px; + height: 300px; + justify-content: space-between; + border-radius: 20px; + margin-bottom: 50px; + margin-top: 300px; +} + +.imageux_bottom { + width: 40px; + height: 40px; + margin-bottom: 32px; +} + +.buttonux { + width: 360px; + height: 90px; + justify-content: space-around; +} \ No newline at end of file diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/control/pages/service/index.hml b/CompleteApps/SmartKettleApp/entry/src/main/js/control/pages/service/index.hml new file mode 100644 index 0000000000000000000000000000000000000000..c656c0c347915b15cea51bb03c27764151b182e3 --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/js/control/pages/service/index.hml @@ -0,0 +1,44 @@ + + +
+ +
+
+
+ + {{$t('strings.repairservice')}} +
+
+ {{$t('strings.service')}} + {{$t('strings.amount')}} +
+ {{$t('strings.serviceTime')}} + {{$t('strings.time')}} + +
+
+
+
+ {{$t('strings.contact')}} +
+
+ {{$t('strings.buyNow')}} +
+
+
+ +
+
\ No newline at end of file diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/control/pages/service/index.js b/CompleteApps/SmartKettleApp/entry/src/main/js/control/pages/service/index.js new file mode 100644 index 0000000000000000000000000000000000000000..3272e4f98542cc6dc8168bb14512defb9137fcb6 --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/js/control/pages/service/index.js @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import router from '@system.router'; + +export default { + data: { + }, + + // Goback to device page. + goBack() { + router.back({ + uri: 'pages/device/index' + }); + }, +}; + diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/control/pages/timer/index.css b/CompleteApps/SmartKettleApp/entry/src/main/js/control/pages/timer/index.css new file mode 100644 index 0000000000000000000000000000000000000000..20d4ffb4d7a3ebf22db1af21920e1149c65e14ea --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/js/control/pages/timer/index.css @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@import '../../common/css/common.css'; + +.flexux { + width: 720px; + height: 250px; + border-radius: 20px; + margin-bottom: 30px; +} + + + + + + + + + diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/control/pages/timer/index.hml b/CompleteApps/SmartKettleApp/entry/src/main/js/control/pages/timer/index.hml new file mode 100644 index 0000000000000000000000000000000000000000..ad40b9b8a30f138a2fb31532798046e47065c24c --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/js/control/pages/timer/index.hml @@ -0,0 +1,47 @@ + + + +
+ +
+
+
+ {{$item.message}} +
+ {{$item.hour}}:{{$item.min}} + +
+ {{$t('strings.dailyExecution')}}{{$item.temp}}℃ +
+
+
+ + + +
+
+ + + + +
+
+ + +
+
+
+
\ No newline at end of file diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/control/pages/timer/index.js b/CompleteApps/SmartKettleApp/entry/src/main/js/control/pages/timer/index.js new file mode 100644 index 0000000000000000000000000000000000000000..70cbbc46f703365fb0052ffd9ef0c7b7c4f933d4 --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/js/control/pages/timer/index.js @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import router from '@system.router'; +import prompt from '@system.prompt'; +export default { + data: { + + message: '', + hour: '', + min: '', + temp: '', + ScheduleList: [], + toast: { + HourMessage: '', + MinMessage: '', + TempMessage: '' + } + + }, + onInit() { + this.toast.HourMessage = this.$t('strings.noMore24'); + this.toast.MinMessage = this.$t('strings.noMore60'); + this.toast.TempMessage = this.$t('strings.noMore100'); + + this.$app.$def.AlarmList[0].message = this.$t('strings.warm'); + this.$app.$def.AlarmList[1].message = this.$t('strings.feeding'); + this.$app.$def.AlarmList[2].message = this.$t('strings.afternoonTea'); + this.$app.$def.AlarmList[3].message = this.$t('strings.gingerTea'); + + this.ScheduleList = this.$app.$def.AlarmList; + }, + + /** + * Get input information + * + * @param e e + */ + getMessage(e) { + this.message = e.text; + }, + + /** + * Get input hour + * + * @param e e + */ + getHour(e) { + if (e.text > 23) { // 23 hours maximum + prompt.showToast({ + message: this.toast.HourMessage + }); + e.text = '00'; + } + this.hour = e.text; + }, + + /** + * Get input Minute + * + * @param e e + */ + getMin(e) { + if (e.text > 59) { // 59 minutes maximum + prompt.showToast({ + message: this.toast.MinMessage + }); + e.text = '00'; + } + this.min = e.text; + }, + + /** + * Get input temperature + * + * @param e e + */ + getTemp(e) { + if (e.text > 100) { // max temperature is 100 + prompt.showToast({ + message: this.toast.TempMessage + }); + e.text = '100'; + } + this.temp = e.text; + }, + + /** + * Push informations into AlarmList object. + * + * @param e e + */ + setSchedule(e) { + // If it is less than 10, ten digits are supplemented by 0 + if (Number(this.hour) < 10) { + this.hour = '0' + this.hour; + } + // If it is less than 10, ten digits are supplemented by 0 + if (Number(this.min) < 10) { + this.min = '0' + this.min; + } + let addItem = { + message: this.message, + hour: this.hour, + min: this.min, + temp: this.temp, + state: 1, + }; + this.$app.$def.AlarmList.push(addItem); + this.$element('datedialog').close(); + }, + + // Show dialog. + addSchedule() { + this.$element('datedialog').show(); + }, + + // Close dialog. + cancelSchedule() { + this.$element('datedialog').close(); + }, + + // Change AlarmList object state value. + switchChange(index, e) { + if (e.checked) { + this.$app.$def.AlarmList[index].state = 1; + } else { + this.$app.$def.AlarmList[index].state = 0; + } + }, + + // Delete one an AlarmList object. + deleteItem(index, e) { + this.$app.$def.AlarmList.splice(index, 1); + }, +}; \ No newline at end of file diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/default/app.js b/CompleteApps/SmartKettleApp/entry/src/main/js/default/app.js new file mode 100644 index 0000000000000000000000000000000000000000..611940d2460ba77370a5e5ab53acb0439df513ce --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/js/default/app.js @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +var FaSoftapUtil = require('fa-softaputil'); + +export default { + onCreate() { + }, + onDestroy() { + }, + faSoftapUtil: FaSoftapUtil.FASoftapUtil, +}; diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/default/common/css/common.css b/CompleteApps/SmartKettleApp/entry/src/main/js/default/common/css/common.css new file mode 100644 index 0000000000000000000000000000000000000000..6c39ce0bf12f1f4f4181938c70a8086a3346d252 --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/js/default/common/css/common.css @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +.color_gray { + color: #a0a0a0; +} + +.color_black { + color: #000; +} + +.color_blue { + color: #007dff; +} + +.text_blue { + text-color: #007dff; +} + +.text_white { + text-color: #ffffff; +} + +.font32 { + font-size: 32px; +} + +.font25 { + font-size: 25px; +} + +.font35 { + font-size: 35px; +} + +.back_color { + background-color: #f7f7f7; +} +.back_gray { + background-color: #f0f0f0; +} + +.back_blue { + background-color: #007dff; +} + +.flexcol { + flex-direction: column; +} + +.flexrow { + flex-direction: row; +} + +.jcenter { + justify-content: center; +} +.acenter { + align-items: center; +} +.astart { + align-items: flex-start; +} +.jstart { + justify-content: flex-start; +} + +.bradius36 { + border-radius: 36px; +} + +.mbottom20 { + margin-bottom: 20px; +} + +.mbottom40{ + margin-bottom: 40px; +} + +.logoimgsrc { + margin-top: 106px; + width: 187px; + height: 187px; + margin-bottom: 70px; +} + +.imgsrc { + margin-top: 48px; + width: 314px; + height: 314px; + margin-bottom: 44px; +} + +.dividerux { + width: 1px; + height: 100%; + background-color: rgba(0, 0, 0, 0.2); +} +.flexrow_around { + height: 60px; + justify-content: space-around; + align-items: center; + margin-bottom: 32px; + flex-direction: row; +} + +.textux{ + width: 300px; + background-color: transparent; +} + diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/default/common/img/ic_about.png b/CompleteApps/SmartKettleApp/entry/src/main/js/default/common/img/ic_about.png new file mode 100644 index 0000000000000000000000000000000000000000..8aace76d60e7983c1ce667bdd8d6e00267f86555 Binary files /dev/null and b/CompleteApps/SmartKettleApp/entry/src/main/js/default/common/img/ic_about.png differ diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/default/common/img/ic_normal.png b/CompleteApps/SmartKettleApp/entry/src/main/js/default/common/img/ic_normal.png new file mode 100644 index 0000000000000000000000000000000000000000..883cfe9e535ad4ce2383c409994a92b8ad81adde Binary files /dev/null and b/CompleteApps/SmartKettleApp/entry/src/main/js/default/common/img/ic_normal.png differ diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/default/common/img/ic_wlan.png b/CompleteApps/SmartKettleApp/entry/src/main/js/default/common/img/ic_wlan.png new file mode 100644 index 0000000000000000000000000000000000000000..9c97c823f86a661a21c62cec8f29dc1672fd8667 Binary files /dev/null and b/CompleteApps/SmartKettleApp/entry/src/main/js/default/common/img/ic_wlan.png differ diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/default/common/img/icon.png b/CompleteApps/SmartKettleApp/entry/src/main/js/default/common/img/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..f488f9adbaa27a1425b8b91b251b89de8c02bc0b Binary files /dev/null and b/CompleteApps/SmartKettleApp/entry/src/main/js/default/common/img/icon.png differ diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/default/common/img/light_on.png b/CompleteApps/SmartKettleApp/entry/src/main/js/default/common/img/light_on.png new file mode 100644 index 0000000000000000000000000000000000000000..440509f0b496026017159847606b4ec096d43d53 Binary files /dev/null and b/CompleteApps/SmartKettleApp/entry/src/main/js/default/common/img/light_on.png differ diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/default/common/img/right_grey.png b/CompleteApps/SmartKettleApp/entry/src/main/js/default/common/img/right_grey.png new file mode 100644 index 0000000000000000000000000000000000000000..99733b2fe98246a4d7b8de2831b616de7a4e5b3c Binary files /dev/null and b/CompleteApps/SmartKettleApp/entry/src/main/js/default/common/img/right_grey.png differ diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/default/common/pages/devicelogo/devicelogo.css b/CompleteApps/SmartKettleApp/entry/src/main/js/default/common/pages/devicelogo/devicelogo.css new file mode 100644 index 0000000000000000000000000000000000000000..9749b8538442084abff765e7ecd992e2db303fef --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/js/default/common/pages/devicelogo/devicelogo.css @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@import '../../css/common.css'; +.devicenameux { + color: #000; + font-size: 40px; + margin-bottom: 20px; +} \ No newline at end of file diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/default/common/pages/devicelogo/devicelogo.hml b/CompleteApps/SmartKettleApp/entry/src/main/js/default/common/pages/devicelogo/devicelogo.hml new file mode 100644 index 0000000000000000000000000000000000000000..40f2753f75065e07603a2ba3fa0b065e5dbfeb46 --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/js/default/common/pages/devicelogo/devicelogo.hml @@ -0,0 +1,21 @@ + + +
+
+ + {{device_name}} +
+
\ No newline at end of file diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/default/common/pages/devicelogo/devicelogo.js b/CompleteApps/SmartKettleApp/entry/src/main/js/default/common/pages/devicelogo/devicelogo.js new file mode 100644 index 0000000000000000000000000000000000000000..6554ec4ffb73f5818568c7f950f9790fde5de41e --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/js/default/common/pages/devicelogo/devicelogo.js @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import app from '@system.app'; +import router from '@system.router'; +export default { + props: [ + 'logo_img', + 'device_name', + ], + +} \ No newline at end of file diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/default/common/pages/logotitle/logotitle.css b/CompleteApps/SmartKettleApp/entry/src/main/js/default/common/pages/logotitle/logotitle.css new file mode 100644 index 0000000000000000000000000000000000000000..2a5530171b23d2789469b8041248fdd9d563f869 --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/js/default/common/pages/logotitle/logotitle.css @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@import '../../css/common.css'; +.titleux { + font-size: 45px; + margin-bottom: 70px; +} \ No newline at end of file diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/default/common/pages/logotitle/logotitle.hml b/CompleteApps/SmartKettleApp/entry/src/main/js/default/common/pages/logotitle/logotitle.hml new file mode 100644 index 0000000000000000000000000000000000000000..4f3d6045f56e3930b0c823fb7e27bc0bd8928a14 --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/js/default/common/pages/logotitle/logotitle.hml @@ -0,0 +1,21 @@ + + +
+
+ + {{title_text}} +
+
\ No newline at end of file diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/default/common/pages/logotitle/logotitle.js b/CompleteApps/SmartKettleApp/entry/src/main/js/default/common/pages/logotitle/logotitle.js new file mode 100644 index 0000000000000000000000000000000000000000..4b1a65af865d8f4f0a44acaa419a158048ab852c --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/js/default/common/pages/logotitle/logotitle.js @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import app from '@system.app'; +import router from '@system.router'; +export default { + props: [ + 'logo_src', + 'title_text', + ], +}; \ No newline at end of file diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/default/i18n/en-US.json b/CompleteApps/SmartKettleApp/entry/src/main/js/default/i18n/en-US.json new file mode 100644 index 0000000000000000000000000000000000000000..ff965396b8f9c1cdb10a236bd8f87880cec63a51 --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/js/default/i18n/en-US.json @@ -0,0 +1,51 @@ +{ + "strings": { + "versionNum": "Version1.0.0", + "deviceName": "SmartKettle", + "authorizeDescription": "YouNeedToAuthorizeAndLogInWithYourMobilePhone", + "login":"HuaweiAccountLogin", + "cancle":"Cancel", + "determine":"YouAgree", + "privacyStatement":"xxxUserAgreementAndPrivacyStatement", + "apply": "Apply", + "getPhoneNum": "GetYourMobileNumber", + "phoneNum": "18112367889", + "setWifi":"SetWiFi", + "authorization": "Authorization", + "tip": "TheDataSharedToXXXIsGovernedByTheThirdPartyPrivacyStatement.YouCanCancelTheAuthorizationInThePrivacyCenterOfHuaweiAccount", + "networkSet":"NetworkSettings", + "otherNet": "UseOtherWirelessNetworks", + "support": "WLANNetworkSupportedHasBeenProvided", + "buttonOk": "Determine", + "locationSet": "LocationSetting", + "family":"Family", + "myHouse":"MyHome", + "noSupport": "NotSupport", + "getWifiFailed": "FailedToGetWiFiList", + "findFailed":"DeviceDiscoveryFailed", + "connectFailed":"FailedToConnectDevice", + "configFailed": "DeviceDistributionNetworkFailure", + "livingRoom": "LivingRoom", + "bedroom": "BedRoom", + "secondBedroom": "S'BedRoom", + "restaurant": "Restaurant", + "study": "Study", + "Restroom": "Restroom", + "bathroom": "Bathroom", + "balcony": "Balcony", + "readytoconnectInfo": "PleaseConfirmThatTheDeviceHasBeenReset,ClickSetWiFiAndConnect'Kettle_AP'Hotpot,ClickTheStartDistributionButton", + "readytoconnect": "DistributionNetwork", + "notConnectHotSpot": "NotConnected'Kettle_AP'Hotpot", + "configNetError": "DistributionNetworkFailure", + "connectBackInfo": "PleaseConnectBackToTheHotspot" + + }, + "files": { + "logoImg": "/common/img/icon.png", + "icSrc": "/common/img/ic_normal.png", + "aboutSrc":"/common/img/ic_about.png", + "lightOn":"/common/img/light_on.png", + "logoSrc": "/common/img/icon.png", + "rightSrc":"/common/img/right_grey.png" + } +} \ No newline at end of file diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/default/i18n/zh-CN.json b/CompleteApps/SmartKettleApp/entry/src/main/js/default/i18n/zh-CN.json new file mode 100644 index 0000000000000000000000000000000000000000..fbbd6f675ba8577af1425033e395f8d1620913da --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/js/default/i18n/zh-CN.json @@ -0,0 +1,51 @@ +{ + "strings": { + "versionNum": "版本1.0.0", + "deviceName": "智能恒温热水壶", + "authorizeDescription": "继续使用需要授权并用手机号登录", + "login":"华为账号快速登录", + "cancle":"取消", + "determine":"登录表示您同意", + "privacyStatement":"xxx用户协议和隐私声明", + "apply": "申请", + "getPhoneNum": "获取您的手机号码", + "phoneNum": "18112367889", + "authorization": "授权", + "tip": "分享给xxx的数据由第三方隐私声明管辖。您可以随时在华为账号的隐私中心中取消授权", + "networkSet":"网络设置", + "otherNet": "使用其它无线网络", + "support": "已为您提供设备支持的WLAN网络", + "buttonOk": "确定", + "locationSet": "位置设置", + "family":"家庭", + "setWifi":"设置wifi", + "myHouse":"我的家", + "noSupport": "不支持", + "getWifiFailed": "获取wifi列表失败", + "findFailed":"发现设备失败", + "connectFailed":"连接设备失败", + "configFailed": "设备配网失败", + "livingRoom": "客厅", + "bedroom": "卧室", + "secondBedroom": "次卧", + "restaurant": "餐厅", + "study": "书房", + "Restroom": "洗手间", + "bathroom": "浴室", + "balcony": "阳台", + "readytoconnectInfo": "请确定设备已经复位后,点击设置wifi 并连接Kettle_AP热点后,再点击开始配网按钮", + "readytoconnect": "开始配网", + "notConnectHotSpot": "尚未连接Kettle_AP热点", + "configNetError": "配网失败", + "connectBackInfo": "请连接回热点" + + }, + "files": { + "logoImg": "/common/img/icon.png", + "icSrc": "/common/img/ic_normal.png", + "aboutSrc":"/common/img/ic_about.png", + "lightOn":"/common/img/light_on.png", + "logoSrc": "/common/img/icon.png", + "rightSrc":"/common/img/right_grey.png" + } +} \ No newline at end of file diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/default/pages/confignet/index.css b/CompleteApps/SmartKettleApp/entry/src/main/js/default/pages/confignet/index.css new file mode 100644 index 0000000000000000000000000000000000000000..7a4dd9004d39a802bd6abf77fd0775c14ba0502a --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/js/default/pages/confignet/index.css @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@import '../../common/css/common.css'; + +.buttonux { + margin-left: 32px; + width: 90%; + height: 80px; + background-color: transparent; + margin-bottom: 60px; + border-bottom-style: solid; + border-bottom-width: 2px; + border-bottom-color: rgba(0, 0, 0, 0.2); +} \ No newline at end of file diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/default/pages/confignet/index.hml b/CompleteApps/SmartKettleApp/entry/src/main/js/default/pages/confignet/index.hml new file mode 100644 index 0000000000000000000000000000000000000000..b4546f36fac52cb1004002a19f8543d4c8ac8262 --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/js/default/pages/confignet/index.hml @@ -0,0 +1,33 @@ + + + +
+ +
+
+ +
+
+ +
+ {{$t('strings.otherNet')}} +
+
+ +
+ +
+
\ No newline at end of file diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/default/pages/confignet/index.js b/CompleteApps/SmartKettleApp/entry/src/main/js/default/pages/confignet/index.js new file mode 100644 index 0000000000000000000000000000000000000000..061830cb087009e17a0cf3b1394c05ec5d806019 --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/js/default/pages/confignet/index.js @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import router from '@system.router'; +import prompt from '@system.prompt'; + +var fanConstants = require('fan-constants'); + +export default { + data: { + oldWifi: '', + wifiName: '', + wifiPassword: '', + NetworkFlag: false, + text: '' + }, + onInit() { + this.text = this.$t('strings.buttonOk'); + this.wifiName = this.oldWifi; + }, + + // goto locationset page. + goBack() { + router.push({ + uri: 'pages/phone/index' + }); + }, + + // Call find Device interface. + goNext() { + let that = this; + this.NetworkFlag = true; + let wifiName = this.wifiName; + + let data = {}; + data.cmd = 0x20; + let param = {}; + param.wifiName = this.wifiName; + param.wifiPassword = this.wifiPassword; + data.param = param; + let toastConfigNetError = this.$t('strings').configNetError; + this.$app.$def.faSoftapUtil.sendMessage(data, fanConstants.CONSTANTS.SET_WIFI_CODE).then(function (res) { + let result = JSON.parse(res); + if (result.code === 200) { + // get serverip + let serverIp = ''; + router.push({ + uri: 'pages/locationset/index', + params: { + serverIp: result.result.ip, + wifiName: wifiName + } + }); + } else { + prompt.showToast({ + message: toastConfigNetError + result.errmsg + }); + that.NetworkFlag = false; + } + }); + }, + changeWifiName(e) { + this.wifiName = e.value; + }, + changeWifiPassword(e) { + this.wifiPassword = e.value; + }, + useOtherNet() { + router.push({ + uri: 'pages/otherWifi/index', + }); + } +}; \ No newline at end of file diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/default/pages/index/index.css b/CompleteApps/SmartKettleApp/entry/src/main/js/default/pages/index/index.css new file mode 100644 index 0000000000000000000000000000000000000000..c209a34d78e1b016012806fdfa75a5b9d00e4c14 --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/js/default/pages/index/index.css @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@import '../../common/css/common.css'; + +.imageux { + margin-right: 20px; + width: 60px; + height: 60px; +} \ No newline at end of file diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/default/pages/index/index.hml b/CompleteApps/SmartKettleApp/entry/src/main/js/default/pages/index/index.hml new file mode 100644 index 0000000000000000000000000000000000000000..6af10ad799e47359086e76c6162251c38d931cf7 --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/js/default/pages/index/index.hml @@ -0,0 +1,35 @@ + + + +
+
+ + {{$t('strings.versionNum')}} + {{$t('strings.authorizeDescription')}} + +
+ + {{$t('strings.login')}} +
+
+ {{$t('strings.cancle')}} +
+
+ {{$t('strings.determine')}} + {{$t('strings.privacyStatement')}} +
+
+
\ No newline at end of file diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/default/pages/index/index.js b/CompleteApps/SmartKettleApp/entry/src/main/js/default/pages/index/index.js new file mode 100644 index 0000000000000000000000000000000000000000..cad78d4c23629fef435be3abd6f07a7491836047 --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/js/default/pages/index/index.js @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import router from '@system.router'; +import app from '@system.app'; +export default { + data: { + + }, + onInit() { + }, + + // Goto phone page. + goNext() { + router.push({ + uri: 'pages/phone/index' + }); + }, + + // Exit the current ability. + goBack() { + app.terminate(); + } +}; diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/default/pages/locationset/index.css b/CompleteApps/SmartKettleApp/entry/src/main/js/default/pages/locationset/index.css new file mode 100644 index 0000000000000000000000000000000000000000..26d7df80dbedb770c323f4df6eb98f03d09d5257 --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/js/default/pages/locationset/index.css @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@import '../../common/css/common.css'; + +.rightsrcux { + width: 15px; + height: 27px; + margin-top: 10px; +} + +.homeux { + margin-left: 32px; + margin-right: 32px; + justify-content: space-around; + margin-top: 48px; + flex-wrap: wrap; + margin-bottom: 48px; +} + +.homeitemux { + font-weight: 500; + font-size: 24px; + width: 138px; + height: 50px; + margin-top: 20px; + text-color: #000; + margin-right: 2px; +} diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/default/pages/locationset/index.hml b/CompleteApps/SmartKettleApp/entry/src/main/js/default/pages/locationset/index.hml new file mode 100644 index 0000000000000000000000000000000000000000..2e6d1eac296934df0a93eb86cdf568b0827c2d32 --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/js/default/pages/locationset/index.hml @@ -0,0 +1,38 @@ + + + +
+ +
+ {{ $t('strings.family') }} +
+ {{ + $t('strings.myHouse') }} + +
+
+
+
+ +
+
+ +
+ +
+ +
+
diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/default/pages/locationset/index.js b/CompleteApps/SmartKettleApp/entry/src/main/js/default/pages/locationset/index.js new file mode 100644 index 0000000000000000000000000000000000000000..d2d3dce0a8ffec272542913b35a316e21f8db62e --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/js/default/pages/locationset/index.js @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import prompt from '@system.prompt'; +import app from '@system.app'; + +var fanConstants = require('fan-constants'); + +export default { + data: { + wifiName: '', + serverIp: '', + DeviceSettings: [ + { + name: '', + backcolor: 'rgba(0, 175, 255, 0.2)' + }, + { + name: '', + backcolor: 'rgba(0, 0, 0, 0.1)' + }, + { + name: '', + backcolor: 'rgba(0, 0, 0, 0.1)' + }, + { + name: '', + backcolor: 'rgba(0, 0, 0, 0.1)' + }, + { + name: '', + backcolor: 'rgba(0, 0, 0, 0.1)' + }, + { + name: '', + backcolor: 'rgba(0, 0, 0, 0.1)' + }, + { + name: '', + backcolor: 'rgba(0, 0, 0, 0.1)' + }, + { + name: '', + backcolor: 'rgba(0, 0, 0, 0.1)' + } + ], + }, + onInit() { + this.DeviceSettings[0].name = this.$t('strings.livingRoom'); + this.DeviceSettings[1].name = this.$t('strings.bedroom'); + this.DeviceSettings[2].name = this.$t('strings.secondBedroom'); + this.DeviceSettings[3].name = this.$t('strings.restaurant'); + + this.DeviceSettings[4].name = this.$t('strings.study'); + this.DeviceSettings[5].name = this.$t('strings.Restroom'); + this.DeviceSettings[6].name = this.$t('strings.bathroom'); + this.DeviceSettings[7].name = this.$t('strings.balcony'); + }, + +// Goback to confignet page. + goBack() { + app.terminate(); + }, + +// Config network successfully entered the control page,and pass parameter:sessionId. + goNext() { + console.info('aaaaa:' + this.serverIp); + let data = {}; + let wifiName = this.wifiName; + let ToastMes = this.$t('strings.connectBackInfo') + wifiName; + let serverIp = this.serverIp; + let faSoftapUtil = this.$app.$def.faSoftapUtil; + + this.$app.$def.faSoftapUtil.sendMessage(data, fanConstants.CONSTANTS.GET_CURRENT_WIFI_CODE).then(function (res) { + if (res === wifiName) { + let info = { + serverIp: serverIp + }; + faSoftapUtil.callNewFa(info, 0); + app.terminate(); + } else { + prompt.showToast({ + message: ToastMes + }); + } + }); + }, +}; \ No newline at end of file diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/default/pages/otherWifi/index.css b/CompleteApps/SmartKettleApp/entry/src/main/js/default/pages/otherWifi/index.css new file mode 100644 index 0000000000000000000000000000000000000000..bb9625b7add2b256252493e47318f9f0c0bc0d42 --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/js/default/pages/otherWifi/index.css @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +@import '../../common/css/common.css'; + +.container { + flex-direction: column; + justify-content: center; + padding-top: 30px; + margin: 0 82px; +} + +.title { + font-size: 42px; +} + +.subtitle { + margin: 20px 0; + font-size: 24px; + opacity: .8; +} + +.list { +} + +.list-item { + height: 124px; + justify-content: space-between; + align-items: center; + border-bottom: 1px solid #000; + +} + +.list-text-box { + flex-direction: column; + justify-content: center; +} + +.ssid { + font-size: 32px; +} + +.tag { + font-size: 28px; + padding-top: 10px; + opacity: .8; +} + +.right-image { + width: 48px; + height: 48px; +} +.cancel { + margin-bottom: 50px; +} + + diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/default/pages/otherWifi/index.hml b/CompleteApps/SmartKettleApp/entry/src/main/js/default/pages/otherWifi/index.hml new file mode 100644 index 0000000000000000000000000000000000000000..87f15b671e6bdb5d2f07ec3c5842f1f49fb6f1bc --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/js/default/pages/otherWifi/index.hml @@ -0,0 +1,36 @@ + + +
+ + {{ $t('strings.otherNet') }} + + + {{ $t('strings.support') }} + + + + +
+ {{ $item.ssid }} + {{ $item.security }} +
+ +
+
+
+ +
+ diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/default/pages/otherWifi/index.js b/CompleteApps/SmartKettleApp/entry/src/main/js/default/pages/otherWifi/index.js new file mode 100644 index 0000000000000000000000000000000000000000..1f19c25804e80e7e523463efca190686de6ac184 --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/js/default/pages/otherWifi/index.js @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import router from '@system.router'; +import prompt from '@system.prompt'; + +var fanConstants = require('fan-constants'); + +export default { + data: { + wifiList: [] + }, + onInit() { + console.info('time control init'); + }, + onShow() { + this.refreshList(); + }, + cancel() { + router.back(); + }, + clickItem(index) { + if (index === 0) { + router.back(); + } + else { + router.push({ + uri: 'pages/confignet/index', + params: { + oldWifi: this.wifiList[index].ssid + } + }); + } + }, + refreshList() { + let data = {}; + let that = this; + this.$app.$def.faSoftapUtil.sendMessage(data, fanConstants.CONSTANTS.GET_AVAILABLE_WIFI_CODE).then(function + (res) { + let result = JSON.parse(res); + console.info('aaaaa ' + res); + if (result.code === 200) { + // get serverip + that.wifiList = result.wifi; + } else { + prompt.showToast({ + message: result.errMsg + }); + } + }); + } +}; diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/default/pages/phone/index.css b/CompleteApps/SmartKettleApp/entry/src/main/js/default/pages/phone/index.css new file mode 100644 index 0000000000000000000000000000000000000000..d3e1d11d8bf0bade2a97b9bd163a9908bc24d34b --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/js/default/pages/phone/index.css @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@import '../../common/css/common.css'; + +.aboutsrcux { + margin-left: 10px; + width: 35px; + height: 35px; +} + +.lightonsrcux { + width: 50px; + height: 50px; +} diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/default/pages/phone/index.hml b/CompleteApps/SmartKettleApp/entry/src/main/js/default/pages/phone/index.hml new file mode 100644 index 0000000000000000000000000000000000000000..34fd6b97067422ec2b94bc98ce96ea94360a8c7d --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/js/default/pages/phone/index.hml @@ -0,0 +1,31 @@ + + + +
+ +
+ + {{$t('strings.readytoconnectInfo')}} + +
+
+ {{$t('strings.setWifi')}} +
+
+ + +
+
\ No newline at end of file diff --git a/CompleteApps/SmartKettleApp/entry/src/main/js/default/pages/phone/index.js b/CompleteApps/SmartKettleApp/entry/src/main/js/default/pages/phone/index.js new file mode 100644 index 0000000000000000000000000000000000000000..1fb3770e213380a229e8b23bdd50b06a2739443e --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/js/default/pages/phone/index.js @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import router from '@system.router'; +import prompt from '@system.prompt'; +import app from '@system.app'; + +var fanConstants = require("fan-constants"); + +export default { + data: { + oldWifi: "" + }, + onInit: async function() { + let data = {}; + let wifi = await this.$app.$def.faSoftapUtil.sendMessage(data, fanConstants.CONSTANTS.GET_CURRENT_WIFI_CODE); + if (wifi !== fanConstants.CONSTANTS.SMARTFAN_WIFI) { + this.oldWifi = wifi; // Record the wifi name before + } + }, + + /** + * Call isSupportWifiAware interface + * + * @return result.code + */ + onReady: function () { + }, + + // Support wifiware and goto confignet page. + goNext: function () { + let data = {}; + let wifi = this.oldWifi; + let ToastMes = this.$t('strings.notConnectHotSpot'); + this.$app.$def.faSoftapUtil.sendMessage(data, fanConstants.CONSTANTS.GET_CURRENT_WIFI_CODE).then(function (res) + { + if (res === fanConstants.CONSTANTS.SMARTFAN_WIFI) { + router.push({ + uri: "pages/confignet/index", + params: { + oldWifi: wifi + } + }) + } else { + prompt.showToast({ + message: ToastMes + }); + } + }); + }, + + // Exit the current ability. + goBack() { + app.terminate(); + }, + async goSetWifi() { + var action = {}; + action.bundleName = "com.android.settings"; + action.abilityName = "com.android.settings.Settings$WifiSettingsActivity"; + action.flag = 16; + // Intent.FLAG_NOT_OHOS_COMPONENT + action.data = {}; + await FeatureAbility.startAbility(action); + } +}; \ No newline at end of file diff --git a/CompleteApps/SmartKettleApp/entry/src/main/resources/base/element/string.json b/CompleteApps/SmartKettleApp/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f0b24948f3e3ec74f588f6764a28ba323b00d70c --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/resources/base/element/string.json @@ -0,0 +1,27 @@ +{ + "string": [ + { + "name": "app_name", + "value": "智能恒温热水壶" + }, + { + "name": "mainability_description", + "value": "JS_Phone_Empty Feature Ability" + }, + { + "name": "controlability_description", + "value": "hap sample empty page" + }, + { + "name": "ControlServer_description", + "value": "hap sample empty service" + }, + { + "name": "forpublic", + "value": "公开" + }, { + "name": "encrypt", + "value": "加密" + } + ] +} \ No newline at end of file diff --git a/CompleteApps/SmartKettleApp/entry/src/main/resources/base/media/icon.png b/CompleteApps/SmartKettleApp/entry/src/main/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..2ad2b5ea004abaee13e71dc96f56891047bae494 Binary files /dev/null and b/CompleteApps/SmartKettleApp/entry/src/main/resources/base/media/icon.png differ diff --git a/CompleteApps/SmartKettleApp/entry/src/main/resources/en/element/string.json b/CompleteApps/SmartKettleApp/entry/src/main/resources/en/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..257a33d3b0c660f6166484c8e36dcf8031fa345d --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/resources/en/element/string.json @@ -0,0 +1,27 @@ +{ + "string": [ + { + "name": "app_name", + "value": "SmartKettle" + }, + { + "name": "mainability_description", + "value": "JS_Phone_Empty Feature Ability" + }, + { + "name": "controlability_description", + "value": "hap sample empty page" + }, + { + "name": "ControlServer_description", + "value": "hap sample empty service" + }, + { + "name": "forpublic", + "value": "public" + }, { + "name": "encrypt", + "value": "encrypt" + } + ] +} \ No newline at end of file diff --git a/CompleteApps/SmartKettleApp/entry/src/main/resources/zh/element/string.json b/CompleteApps/SmartKettleApp/entry/src/main/resources/zh/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f0b24948f3e3ec74f588f6764a28ba323b00d70c --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/main/resources/zh/element/string.json @@ -0,0 +1,27 @@ +{ + "string": [ + { + "name": "app_name", + "value": "智能恒温热水壶" + }, + { + "name": "mainability_description", + "value": "JS_Phone_Empty Feature Ability" + }, + { + "name": "controlability_description", + "value": "hap sample empty page" + }, + { + "name": "ControlServer_description", + "value": "hap sample empty service" + }, + { + "name": "forpublic", + "value": "公开" + }, { + "name": "encrypt", + "value": "加密" + } + ] +} \ No newline at end of file diff --git a/CompleteApps/SmartKettleApp/entry/src/ohosTest/java/ohos/samples/smartkettle/ExampleOhosTest.java b/CompleteApps/SmartKettleApp/entry/src/ohosTest/java/ohos/samples/smartkettle/ExampleOhosTest.java new file mode 100644 index 0000000000000000000000000000000000000000..561e46286f4bf9fa8f02a997ed601e871bf27301 --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/ohosTest/java/ohos/samples/smartkettle/ExampleOhosTest.java @@ -0,0 +1,14 @@ +package ohos.samples.smartkettle; + +import ohos.aafwk.ability.delegation.AbilityDelegatorRegistry; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class ExampleOhosTest { + @Test + public void testBundleName() { + final String actualBundleName = AbilityDelegatorRegistry.getArguments().getTestBundleName(); + assertEquals("ohos.samples.smartkettle", actualBundleName); + } +} \ No newline at end of file diff --git a/CompleteApps/SmartKettleApp/entry/src/test/java/ohos/samples/smartkettle/ExampleTest.java b/CompleteApps/SmartKettleApp/entry/src/test/java/ohos/samples/smartkettle/ExampleTest.java new file mode 100644 index 0000000000000000000000000000000000000000..6fb74f115e2cf24e55f66d7a7f3fdf33220ef3b4 --- /dev/null +++ b/CompleteApps/SmartKettleApp/entry/src/test/java/ohos/samples/smartkettle/ExampleTest.java @@ -0,0 +1,9 @@ +package ohos.samples.smartkettle; + +import org.junit.Test; + +public class ExampleTest { + @Test + public void onStart() { + } +} diff --git a/CompleteApps/SmartKettleApp/screenshoot/phone/kettle_control.png b/CompleteApps/SmartKettleApp/screenshoot/phone/kettle_control.png new file mode 100644 index 0000000000000000000000000000000000000000..771667c6a0dbc9aa761f42027cdb61e962a9af8c Binary files /dev/null and b/CompleteApps/SmartKettleApp/screenshoot/phone/kettle_control.png differ diff --git a/CompleteApps/SmartKettleApp/screenshoot/phone/kettle_response.PNG b/CompleteApps/SmartKettleApp/screenshoot/phone/kettle_response.PNG new file mode 100644 index 0000000000000000000000000000000000000000..e61206a4e69cdd85d90452cb1ebbe85601b8c22a Binary files /dev/null and b/CompleteApps/SmartKettleApp/screenshoot/phone/kettle_response.PNG differ diff --git a/CompleteApps/SmartKettleApp/screenshoot/phone/smartkettle_1.png b/CompleteApps/SmartKettleApp/screenshoot/phone/smartkettle_1.png new file mode 100644 index 0000000000000000000000000000000000000000..5beeb58187ba6e913557445891b1cb6dce4d81ed Binary files /dev/null and b/CompleteApps/SmartKettleApp/screenshoot/phone/smartkettle_1.png differ diff --git a/CompleteApps/SmartKettleApp/screenshoot/phone/smartkettle_2.png b/CompleteApps/SmartKettleApp/screenshoot/phone/smartkettle_2.png new file mode 100644 index 0000000000000000000000000000000000000000..bfebc213850db8b41614a5f046e5bdd9ad418ecd Binary files /dev/null and b/CompleteApps/SmartKettleApp/screenshoot/phone/smartkettle_2.png differ diff --git a/CompleteApps/SmartKettleApp/screenshoot/phone/smartkettle_3.png b/CompleteApps/SmartKettleApp/screenshoot/phone/smartkettle_3.png new file mode 100644 index 0000000000000000000000000000000000000000..a359e3e9829b46a32640c78605f5ce07d93ef23f Binary files /dev/null and b/CompleteApps/SmartKettleApp/screenshoot/phone/smartkettle_3.png differ diff --git a/CompleteApps/SmartKettleApp/settings.gradle b/CompleteApps/SmartKettleApp/settings.gradle new file mode 100644 index 0000000000000000000000000000000000000000..4773db73233a570c2d0c01a22e75321acfbf7a07 --- /dev/null +++ b/CompleteApps/SmartKettleApp/settings.gradle @@ -0,0 +1 @@ +include ':entry' diff --git a/CompleteApps/SmartKettleDevice/README_zh.md b/CompleteApps/SmartKettleDevice/README_zh.md new file mode 100644 index 0000000000000000000000000000000000000000..3e320e3399d2b5e1fdfbd3a1d573c2e02da3365d --- /dev/null +++ b/CompleteApps/SmartKettleDevice/README_zh.md @@ -0,0 +1,61 @@ +# 智能恒温热水壶代码介绍 + +### 简介 + +​ 本Sample是基于OpenHarmony轻量级系统,利用内核的实时性和丰富的外设拓展功能,模拟智能热水壶设备跟[手机侧热水壶应用](https://gitee.com/openharmony/app_samples/tree/master/CompleteApps/SmartKettleApp/)通信,实现水壶模式控制、温度上报、模拟定时喝水提醒。 + + + +### 使用说明 + +##### 1. 编译步骤 + +1)拷贝本Sample目录下的common、kettle 文件夹到OpenHarmony 系统源码中的applications/sample/wifi-iot/app目录下。 + +2) 修改applications/sample/wifi-iot/app/BUILD.gn 文件,在features字段中增加索引,使目标模块参与编译。features字段指定业务模块的路径和目标,具体配置如下。 + +``` + import("//build/lite/config/component/lite_component.gni") + + lite_component("app") { + features = [ + "kettle", + ] + deps = [ "//applications/sample/wifi-iot/app/common/hals:hals", + "//applications/sample/wifi-iot/app/common/netcfg:netcfg"] +} + +``` + +3)修改hi3861 内核配置文件 + +​ 打开 device/hisilicon/hispark_pegasus/sdk_liteos/build/config/usr_config.mk 文件 + +​ 将 CONFIG_I2C_SUPPORT is not set这一行, 改为CONFIG_I2C_SUPPORT=y + +​ 将 CONFIG_PWM_SUPPORT is not set这一行, 改为CONFIG_PWM_SUPPORT=y + +4) 代码编译和烧录请参考:[链接](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/quick-start/quickstart-lite-steps-hi3861-connection.md) + +##### 2. 与手机应用联动 + +1)准备一个wifi热点A,密码和热点名称自定义。 + +2)提前在手机上安装好[智能热水壶手机端软件](https://gitee.com/openharmony/app_samples/tree/master/CompleteApps/SmartKettleApp/),然后在设置应用中连接热点A。 + +3) 打开手机端智能热水壶软件,在热点连接列表中找到Kettle_AP热点并连接,随后点击配网发送热点A相关信息给到热水壶设备端完成配网。 + +4)待配网完成后,可以在手机端自由设置热水壶的工作状态和相应模式。 + + + +### 约束限制 + +硬件:HiSpark Wi-Fi IoT 开发套件(本sample会用到 主控板、OLED拓展板、温度传感器拓展板) + +软件:OpenHarmony 2.0 Canary版本。[链接](https://device.harmonyos.com/cn/docs/start/get-code/sourcecode-acquire-0000001050769927) + +OpenHarmony轻量级开发指导:[链接](https://device.harmonyos.com/cn/docs/start/introduce/quickstart-lite-overview-0000001105598722) + +开发工具下载:[链接 + diff --git a/CompleteApps/SmartKettleDevice/common/hals/BUILD.gn b/CompleteApps/SmartKettleDevice/common/hals/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..b82f85f4bbff5b0827cfd0a59fc4f6bfa3a777b6 --- /dev/null +++ b/CompleteApps/SmartKettleDevice/common/hals/BUILD.gn @@ -0,0 +1,25 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +static_library("hals") { + sources = [ + "src/peripheral_hal.c", + "src/utils_hal.c" + ] + + include_dirs = [ + "//applications/sample/wifi-iot/app/common/include", + "//base/iot_hardware/peripheral/interfaces/kits", + "//device/hisilicon/hispark_pegasus/sdk_liteos/include", + ] +} \ No newline at end of file diff --git a/CompleteApps/SmartKettleDevice/common/hals/src/peripheral_hal.c b/CompleteApps/SmartKettleDevice/common/hals/src/peripheral_hal.c new file mode 100644 index 0000000000000000000000000000000000000000..28488ce9ae10d1f81b01a9515ba238e0fb967d40 --- /dev/null +++ b/CompleteApps/SmartKettleDevice/common/hals/src/peripheral_hal.c @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "peripheral_hal.h" +#include "iot_errno.h" +#include "hi_io.h" +#include "hi_adc.h" +#include "hi_types_base.h" +#include "hi_watchdog.h" +#include "hi_pwm.h" + +unsigned int HalIoSetFunc(HalWifiIotIoName id, const char *val) +{ + if (id == HAL_WIFI_IOT_IO_NAME_MAX) { + return IOT_FAILURE; + } + return hi_io_set_func((hi_io_name)id, val); +} + +unsigned int HalAdcRead(HalWifiIotAdcChannelIndex channel, unsigned short *data, HalWifiIotAdcEquModelSel equModel, + HalWifiIotAdcCurBais curBais, unsigned short rstCnt) +{ + return hi_adc_read((hi_adc_channel_index)channel, (hi_u16*)data, (hi_adc_equ_model_sel)equModel, + (hi_adc_cur_bais)curBais, (hi_u16)rstCnt); +} + +void HalSetWatchDogEnable(int enable) +{ + if (enable == 0) { + hi_watchdog_disable(); + } else { + hi_watchdog_enable(); + } +} + +unsigned int HalPwmStart(uint32 id, uint16 duty, uint16 freq) +{ + return hi_pwm_start((hi_pwm_port)id, (hi_u16)duty, (hi_u16)freq); +} \ No newline at end of file diff --git a/CompleteApps/SmartKettleDevice/common/hals/src/utils_hal.c b/CompleteApps/SmartKettleDevice/common/hals/src/utils_hal.c new file mode 100644 index 0000000000000000000000000000000000000000..ef34078b38618fb154a9eee05d30d31ab7026cbd --- /dev/null +++ b/CompleteApps/SmartKettleDevice/common/hals/src/utils_hal.c @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ohos_types.h" +#include "hi_time.h" +#include "hi_types_base.h" +#include "utils_hal.h" + +void hal_udelay(uint32 us) +{ + hi_udelay((hi_u32)us); +} \ No newline at end of file diff --git a/CompleteApps/SmartKettleDevice/common/include/common_log.h b/CompleteApps/SmartKettleDevice/common/include/common_log.h new file mode 100644 index 0000000000000000000000000000000000000000..3b2f4fc6b0a9dbc6c718194af54247d44fe1274c --- /dev/null +++ b/CompleteApps/SmartKettleDevice/common/include/common_log.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __COMMON_LOG_H__ +#define __COMMON_LOG_H__ + +#include + +#define LOG_D(fmt, args...) printf("[DEBUG][%s|%d]" fmt, __func__, __LINE__, ##args) +#define LOG_I(fmt, args...) printf("[INFO][%s|%d]" fmt, __func__, __LINE__, ##args) +#define LOG_E(fmt, args...) printf("[ERROR][%s|%d]" fmt, __func__, __LINE__, ##args) + +#endif // __COMMON_LOG_H__ \ No newline at end of file diff --git a/CompleteApps/SmartKettleDevice/common/include/network_manager_service.h b/CompleteApps/SmartKettleDevice/common/include/network_manager_service.h new file mode 100644 index 0000000000000000000000000000000000000000..dea8e2629e12a2b0ed44916e9351b3fed98be49b --- /dev/null +++ b/CompleteApps/SmartKettleDevice/common/include/network_manager_service.h @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __NETWORK_MANAGER_SERVICE_H__ +#define __NETWORK_MANAGER_SERVICE_H__ + +typedef enum { + NET_EVENT_NULL, + NET_EVENT_CONFIG, // Config wifi + NET_EVENT_CONFIG_FAIL, // Config wifi failed + NET_EVENT_CONFIG_SUCC, // Config wifi success + NET_EVENT_CONNECTTING, // connectting wifi + NET_EVENT_CONN_FAILED, // connect wifi failed + NET_EVENT_CONNECTTED, // Wifi connected + NET_EVENT_DISCONNECT, // Wifi disconnected + NET_EVENT_RECV_DATA, // Recv message from FA + + NET_EVENT_TYPE_NBR +}NET_EVENT_TYPE; + +typedef enum { + NET_MODE_IDLE, // the idle mode + NET_MODE_CONFIG, // the netcfg in the AP mode + NET_MODE_STA, // the netcfg int the STA mode + + NET_MODE_NBR +}NET_MODE_TYPE; + +typedef enum { + NET_STA_NULL, + NET_STA_CONFIG, // Config wifi + NET_STA_CONNECTTING, // connectting wifi + NET_STA_CONNECTTED, // Wifi connected + NET_STA_DISCONNECT, // Wifi disconnected + + NET_STA_TYPE_NBR +}NET_STA_TYPE; + +/** + * @brief: the network config service callback + * + * @param event reference {@link NET_EVENT_TYPE} + * @param data The data of the event: NET_EVENT_RECV_DATA or NET_EVENT_SEND_DATA + * @since 1.0 + * @version 1.0 + */ +typedef int (*NetManagerEventCallback)(NET_EVENT_TYPE event, void *data); + +/** + * @brief Register the network config task + * + * @param apName -- the name of the device for AP mode + * nEventCallback -- The callback of netcfg module + * @since 1.0 + * @version 1.0 + * + * @return 0 success, -1 failed + */ +int NetManagerRegister(const char *apName, NetManagerEventCallback nEventCallback); + +/** + * @brief Set the network mode. + * + * @param mode : the network module, reference {@NET_MODE_TYPE} + * @since 1.0 + * @version 1.0 + */ +void NetManagerSetNetMode(int mode); + +/** + * @brief Send msg to FA. + * + * @param msg : the msg to send + * @since 1.0 + * @version 1.0 + * + * @return 0 -- success, others -- failed + */ +int NetManagerSendMsg(const char *msg); + +/** + * @brief UnRegister the network config task + * + * @since 1.0 + * @version 1.0 + * + */ +void NetManagerDeinit(void); + +#endif // __NETWORK_MANAGER_SERVICE_H__ \ No newline at end of file diff --git a/CompleteApps/SmartKettleDevice/common/include/peripheral_hal.h b/CompleteApps/SmartKettleDevice/common/include/peripheral_hal.h new file mode 100644 index 0000000000000000000000000000000000000000..370cd942c8fcd2b155c772b6cc389deb87105d88 --- /dev/null +++ b/CompleteApps/SmartKettleDevice/common/include/peripheral_hal.h @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef PERIPHERAL_HAL_H +#define PERIPHERAL_HAL_H + +#include "ohos_types.h" + +/* gpio start */ +typedef enum { + /** GPIO hardware pin 0 */ + HAL_WIFI_IOT_IO_NAME_GPIO_0, + /** GPIO hardware pin 1 */ + HAL_WIFI_IOT_IO_NAME_GPIO_1, + /** GPIO hardware pin 2 */ + HAL_WIFI_IOT_IO_NAME_GPIO_2, + /** GPIO hardware pin 3 */ + HAL_WIFI_IOT_IO_NAME_GPIO_3, + /** GPIO hardware pin 4 */ + HAL_WIFI_IOT_IO_NAME_GPIO_4, + /** GPIO hardware pin 5 */ + HAL_WIFI_IOT_IO_NAME_GPIO_5, + /** GPIO hardware pin 6 */ + HAL_WIFI_IOT_IO_NAME_GPIO_6, + /** GPIO hardware pin 7 */ + HAL_WIFI_IOT_IO_NAME_GPIO_7, + /** GPIO hardware pin 8 */ + HAL_WIFI_IOT_IO_NAME_GPIO_8, + /** GPIO hardware pin 9 */ + HAL_WIFI_IOT_IO_NAME_GPIO_9, + /** GPIO hardware pin 10 */ + HAL_WIFI_IOT_IO_NAME_GPIO_10, + /** GPIO hardware pin 11 */ + HAL_WIFI_IOT_IO_NAME_GPIO_11, + /** GPIO hardware pin 12 */ + HAL_WIFI_IOT_IO_NAME_GPIO_12, + /** GPIO hardware pin 13 */ + HAL_WIFI_IOT_IO_NAME_GPIO_13, + /** GPIO hardware pin 14 */ + HAL_WIFI_IOT_IO_NAME_GPIO_14, + /** Maximum value */ + HAL_WIFI_IOT_IO_NAME_MAX, +} HalWifiIotIoName; + +/** + * @brief set IO function. + * + * @param id -- IO number, reference {@ HalWifiIotIoName}. + * @param val -- the io function value which defined in {@ hi_io.h}. + * + * @return Returns {@link WIFI_IOT_SUCCESS} if the operation is successful; + * returns an error code defined in {@link wifiiot_errno.h} otherwise. + * @since 1.0 + * @version 1.0 + */ +unsigned int HalIoSetFunc(HalWifiIotIoName id, const char *val); +/* gpio end */ + + +/* adc start */ + +/** + * @brief Enumerates ADC channel indexes. + * + */ +typedef enum { + /** Channel 0 */ + HAL_WIFI_IOT_ADC_CHANNEL_0, + /** Channel 1 */ + HAL_WIFI_IOT_ADC_CHANNEL_1, + /** Channel 2 */ + HAL_WIFI_IOT_ADC_CHANNEL_2, + /** Channel 3 */ + HAL_WIFI_IOT_ADC_CHANNEL_3, + /** Channel 4 */ + HAL_WIFI_IOT_ADC_CHANNEL_4, + /** Channel 5 */ + HAL_WIFI_IOT_ADC_CHANNEL_5, + /** Channel 6 */ + HAL_WIFI_IOT_ADC_CHANNEL_6, + /** Channel 7 */ + HAL_WIFI_IOT_ADC_CHANNEL_7, + /** Button value */ + HAL_WIFI_IOT_ADC_CHANNEL_BUTT, +} HalWifiIotAdcChannelIndex; + +/** + * @brief Enumerates analog power control modes. + */ +typedef enum { + /** Automatic control */ + HAL_WIFI_IOT_ADC_CUR_BAIS_DEFAULT, + /** Automatic control */ + HAL_WIFI_IOT_ADC_CUR_BAIS_AUTO, + /** Manual control (AVDD = 1.8 V) */ + HAL_WIFI_IOT_ADC_CUR_BAIS_1P8V, + /** Manual control (AVDD = 3.3 V) */ + HAL_WIFI_IOT_ADC_CUR_BAIS_3P3V, + /** Button value */ + HAL_WIFI_IOT_ADC_CUR_BAIS_BUTT, +} HalWifiIotAdcCurBais; + +/** + * @brief Enumerates equation models. + */ +typedef enum { + /** One-equation model */ + HAL_WIFI_IOT_ADC_EQU_MODEL_1, + /** Two-equation model */ + HAL_WIFI_IOT_ADC_EQU_MODEL_2, + /** Four-equation model */ + HAL_WIFI_IOT_ADC_EQU_MODEL_4, + /** Eight-equation model */ + HAL_WIFI_IOT_ADC_EQU_MODEL_8, + /** Button value */ + HAL_WIFI_IOT_ADC_EQU_MODEL_BUTT, +} HalWifiIotAdcEquModelSel; + +/** + * @brief Reads a piece of sampled data from a specified ADC channel based on the input parameters. + * + * + * + * @param channel Indicates the ADC channel index. + * @param data Indicates the pointer to the address for storing the read data. + * @param equModel Indicates the equation model. + * @param curBais Indicates the analog power control mode. + * @param rstCnt Indicates the count of the time from reset to conversion start. + * One count is equal to 334 ns. The value must range from 0 to 0xFF0. + * @return Returns {@link WIFI_IOT_SUCCESS} if the operation is successful; + * returns an error code defined in {@link wifiiot_errno.h} otherwise. + * @since 1.0 + * @version 1.0 + */ +unsigned int HalAdcRead(HalWifiIotAdcChannelIndex channel, unsigned short *data, HalWifiIotAdcEquModelSel equModel, + HalWifiIotAdcCurBais curBais, unsigned short rstCnt); +/** adc end ****/ + +/** + * @brief set WatchDog enable or disable. + * + * @param enable -- 1 enable, 0 disable. + * + * @since 1.0 + * @version 1.0 + */ +void HalSetWatchDogEnable(int enable); + +/** + * @brief start the pwm. + * + * @param id Port id of PWM + * @param duty The usefull cycles of PWM + * @param freq The total cycles of PWM + * + * @return Returns {@link WIFI_IOT_SUCCESS} if the operation is successful; + * returns an error code defined in {@link wifiiot_errno.h} otherwise. + * @since 1.0 + * @version 1.0 + */ +unsigned int HalPwmStart(uint32 id, uint16 duty, uint16 freq); + +#endif // PERIPHERAL_HAL_H \ No newline at end of file diff --git a/CompleteApps/SmartKettleDevice/common/include/utils_hal.h b/CompleteApps/SmartKettleDevice/common/include/utils_hal.h new file mode 100644 index 0000000000000000000000000000000000000000..fb158c285296d1f53a06127802d4137125f91a4e --- /dev/null +++ b/CompleteApps/SmartKettleDevice/common/include/utils_hal.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __UTILS_HAL_H__ +#define __UTILS_HAL_H__ + +void hal_udelay(uint32 us); + +#endif // __UTILS_HAL_H__ \ No newline at end of file diff --git a/CompleteApps/SmartKettleDevice/common/netcfg/BUILD.gn b/CompleteApps/SmartKettleDevice/common/netcfg/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..7375d33fa8447e4f8276a135d832e46452c45ffb --- /dev/null +++ b/CompleteApps/SmartKettleDevice/common/netcfg/BUILD.gn @@ -0,0 +1,36 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +static_library("netcfg") { + sources = [ + "src/network_config.c", + "src/network_server.c", + "src/network_manager_service.c", + "src/softap.c", + "src/wifi_sta.c" + ] + + include_dirs = [ + "include", + "//applications/sample/wifi-iot/app/common/include", + "//base/iot_hardware/peripheral/interfaces/kits", + "//foundation/communication/wifi_lite/interfaces/wifiservice", + "//kernel/liteos_m/kal/cmsis", + "//kernel/liteos_m/cmsis", + "//third_party/mbedtls/include/mbedtls", + "//utils/native/lite/include", + "//device/hisilicon/hispark_pegasus/sdk_liteos/third_party/lwip_sack/include", + "//device/hisilicon/hispark_pegasus/sdk_liteos/platform/os/Huawei_LiteOS/components/lib/libsec/include", + "//base/security/deviceauth/frameworks/deviceauth_lite/source", + ] +} diff --git a/CompleteApps/SmartKettleDevice/common/netcfg/include/defines.h b/CompleteApps/SmartKettleDevice/common/netcfg/include/defines.h new file mode 100644 index 0000000000000000000000000000000000000000..356434830bed9c80e306ad5d4ba0928cbd909421 --- /dev/null +++ b/CompleteApps/SmartKettleDevice/common/netcfg/include/defines.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef __DEFINES_H__ +#define __DEFINES_H__ + +#include +#include + +#include + +#define LOG_E(fmt, arg...) printf("[ERROR][%s|%d]" fmt, __func__, __LINE__, ##arg) +#define LOG_D(fmt, arg...) printf("[DEBUG][%s|%d]" fmt, __func__, __LINE__, ##arg) +#define LOG_I(fmt, arg...) printf("[INFO ][%s|%d]" fmt, __func__, __LINE__, ##arg) + +#define REQUEST_OK 200 +#define REQUEST_ERR 401 + +#define BUF_SHORT_SIZE 256 +#define AP_NAME "HmosAP" + +#define DELAY_100MS 10 // for function osDelay(), unit 10ms +#define DELAY_200MS (DELAY_100MS * 2) +#define DELAY_500MS (DELAY_100MS * 5) +#define DELAY_1000MS (DELAY_100MS * 10) +#define DELAY_2000MS (DELAY_100MS * 20) +#define DELAY_5000MS (DELAY_100MS * 50) + +#define USLEEP_100MS 100000 // for function usleep(), unit 1us +#define USLEEP_200MS (USLEEP_100MS * 2) +#define USLEEP_500MS (USLEEP_100MS * 5) +#define USLEEP_1000MS (USLEEP_100MS * 10) +#define USLEEP_2000MS (USLEEP_100MS * 20) +#define USLEEP_2500MS (USLEEP_100MS * 25) +#define USLEEP_5000MS (USLEEP_100MS * 50) + +#define ARRAYSIZE(a) (sizeof((a)) / sizeof((a)[0])) + +#endif /* __DEFINES_H__ */ diff --git a/CompleteApps/SmartKettleDevice/common/netcfg/include/network_config.h b/CompleteApps/SmartKettleDevice/common/netcfg/include/network_config.h new file mode 100644 index 0000000000000000000000000000000000000000..3dc477b85d67eb30b0b6d961c683ba1d4b432e79 --- /dev/null +++ b/CompleteApps/SmartKettleDevice/common/netcfg/include/network_config.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __NETWORK_CONFIG_H__ +#define __NETWORK_CONFIG_H__ + +#include "network_manager_service.h" + +#define NET_TASK_STACK_SIZE (1024*8) +#define NET_TASK_PRIO 31 + +/** + * @brief start net config task + * + * @param apName -- the name of the device for AP mode + * nEventCallback -- The NetEvent callback. event reference {@NET_EVENT_TYPE} + * + * @since 1.0 + * @version 1.0 + * + * @return 0 success, -1 failed + */ +int NetCfgStart(const char *apName, NetManagerEventCallback nEventCallback); + +/** + * @brief stop net config task + * + * @since 1.0 + * @version 1.0 + * + */ +void NetCfgStop(void); + +/** + * @brief set net config mode + * @param mode -- reference {@NET_MODE_TYPE} + * + * @since 1.0 + * @version 1.0 + * + */ +void NetCfgSetMode(int mode); + +/** + * @brief start connect the wifi + * @param ssid -- wifi ssid, pwd -- wifi password + * + * @since 1.0 + * @version 1.0 + * + */ +void NetCfgStartConnect(const char *ssid, const char *pwd); + +#endif /* __NETWORK_CONFIG_H__ */ diff --git a/CompleteApps/SmartKettleDevice/common/netcfg/include/network_server.h b/CompleteApps/SmartKettleDevice/common/netcfg/include/network_server.h new file mode 100644 index 0000000000000000000000000000000000000000..fe90b807b629e8867b215c75eda792d9da18492f --- /dev/null +++ b/CompleteApps/SmartKettleDevice/common/netcfg/include/network_server.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __NETWORK_SERVER_H__ +#define __NETWORK_SERVER_H__ + +#include "network_manager_service.h" + +#define NETSERVER_TASK_STACK_SIZE (1024*4) +#define NETSERVER_TASK_PRIO 33 + + +/** + * @brief start netserver task + * + * @param nEventCallback -- The NetEvent callback, + * when the server recv data, + * it will be called with (@NET_EVENT_RECV_DATA) + * @since 1.0 + * @version 1.0 + * + * @return 0 success, -1 failed + */ +int NetServerInit(NetManagerEventCallback nEventCallback); + +/** + * @brief stop netserver task + * + * @since 1.0 + * @version 1.0 + * + */ +void NetServerDeinit(void); + +/** + * @brief set netserver task resume + * + * @since 1.0 + * @version 1.0 + * + */ +void NetServerStart(void); + +/** + * @brief set netserver task suspend + * + * @since 1.0 + * @version 1.0 + * + */ +void NetServerStop(void); + +/** + * @brief check the netserver when suspend or not. + * + * @since 1.0 + * @version 1.0 + * + * @return true -- netserver task is activity, false -- netserver is suspend + */ +bool NetServerIsRun(void); + +/** + * @brief send msg to client + * @param msg -- The message to send + * + * @since 1.0 + * @version 1.0 + * + * @return 0 success, -1 failed + */ +int NetServerSendMsg(const char *msg); + +#endif /* __NETWORK_SERVER_H__ */ diff --git a/CompleteApps/SmartKettleDevice/common/netcfg/include/softap.h b/CompleteApps/SmartKettleDevice/common/netcfg/include/softap.h new file mode 100644 index 0000000000000000000000000000000000000000..020d475a3fd5c30d76f2fc8e3d228fa95de51290 --- /dev/null +++ b/CompleteApps/SmartKettleDevice/common/netcfg/include/softap.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __SOFT_AP_H__ +#define __SOFT_AP_H__ + +/** + * @brief start ap mode. + * + * @since 1.0 + * @version 1.0 + * + * @return 0 success, -1 failed + */ +int SoftApStart(const char *ap_name); + +/** + * @brief stop ap mode. + * + * @since 1.0 + * @version 1.0 + * + */ +void SoftApStop(void); + +#endif /* __SOFT_AP_H__ */ diff --git a/CompleteApps/SmartKettleDevice/common/netcfg/include/wifi_sta.h b/CompleteApps/SmartKettleDevice/common/netcfg/include/wifi_sta.h new file mode 100644 index 0000000000000000000000000000000000000000..8d05ee0cf2e2abc4fa242e0c3c3f8b41a18e7ea9 --- /dev/null +++ b/CompleteApps/SmartKettleDevice/common/netcfg/include/wifi_sta.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __WIFI_STA_H__ +#define __WIFI_STA_H__ + +#include "wifi_device.h" + +/** + * @brief wifi state change callback. + * @param state -- wifi state, 0 -- wifi not connect, 1 -- wifi connectted + * + * @since 1.0 + * @version 1.0 + * + */ +typedef void (*WifiChangeEvent)(int state); + +/** + * @brief start sta mode. + * @param WifiChange--wifi state changed callback + * + * @since 1.0 + * @version 1.0 + * + * @return 0 success, -1 failed + */ +int WifiStaStart(WifiChangeEvent WifiChange); + +/** + * @brief start connect wifi. + * @param ssid -- wifi ssid, pwd -- wifi password + * + * @since 1.0 + * @version 1.0 + * + * @return 0 success, -1 failed + */ +int WifiStaConnect(const char *ssid, const char *pwd); + +/** + * @brief stop sta mode. + * + * @since 1.0 + * @version 1.0 + * + */ +void WifiStaStop(void); + +#endif /* __WIFI_STA_H__ */ diff --git a/CompleteApps/SmartKettleDevice/common/netcfg/src/network_config.c b/CompleteApps/SmartKettleDevice/common/netcfg/src/network_config.c new file mode 100644 index 0000000000000000000000000000000000000000..93dda4b14f46e2c9ee832a8276778dd62b87639e --- /dev/null +++ b/CompleteApps/SmartKettleDevice/common/netcfg/src/network_config.c @@ -0,0 +1,424 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "errno.h" +#include "cmsis_os2.h" +#include "base64.h" +#include "sys/time.h" +#include "sys/socket.h" +#include "netinet/in.h" +#include "lwip/inet.h" +#include "lwip/netdb.h" + +#include "json/jsonutil.h" +#include "ohos_types.h" +#include "common_log.h" +#include "softap.h" +#include "wifi_sta.h" + +#include "network_config.h" +#include "network_server.h" +#include "defines.h" + +#define SSID_MAX_LEN 32 +#define PWD_MAX_LEN 32 + +#define NET_PORT 8686 + +#define RETRY_TIMES 5 +#define CONNECT_TIMEOUT 20 + +#define CMD_KEY "cmd" +#define PAR_KEY "param" +#define VAL_KEY "wifiName" +#define PWD_KEY "wifiPassword" + +#define CMD_CONFIG 0x20 + +typedef struct { + NET_MODE_TYPE mode; + NET_STA_TYPE status; + bool netRun; + int timeCounts; + + NetManagerEventCallback gEventCall; +} NetManagerInfo; + +static NetManagerInfo g_netManager; +const char *g_apName = NULL; + +#define SET_NET_EVENT(s, e, d) ({ \ + if (g_netManager.gEventCall != NULL) { \ + g_netManager.gEventCall(e, d); \ + } \ + g_netManager.status = s; \ +}) + +static void NetCfgConnectStatus(int s) +{ + if (s == 1 && g_netManager.status != NET_STA_CONNECTTED) { + g_netManager.status = NET_STA_CONNECTTED; + } else if (s == 0) { + if (g_netManager.status == NET_STA_CONNECTTED) { + g_netManager.status = NET_STA_DISCONNECT; + } + g_netManager.mode = NET_MODE_IDLE; + } +} + +#define SHIFT_MASK 0xff +#define SHIFT_8BIT(a) (((a) >> 8) & (SHIFT_MASK)) +#define SHIFT_16BIT(a) (((a) >> 16) & (SHIFT_MASK)) +#define SHIFT_24BIT(a) (((a) >> 24) & (SHIFT_MASK)) + +static void GetIpString(uint32_t ip, char *ipAddr, int size) +{ + if (ipAddr == NULL || size <= 0) { + return; + } + + if (sprintf_s(ipAddr, size, "%d.%d.%d.%d", ip & SHIFT_MASK, SHIFT_8BIT(ip), SHIFT_16BIT(ip), SHIFT_24BIT(ip)) < 0) { + LOG_E("GetIpString failed! \n"); + } + LOG_D("ipAddr : %s \n", ipAddr); +} + +int DeviceGetIp(char *buff, int size) +{ + int ret; + long ip; + struct netif *netif_node = netif_find("wlan0"); + if (netif_node == NULL) { + LOG_E("GetLocalWifiIp netif get fail\r\n"); + return -1; + } + + ip4_addr_t ipAddr; + ip4_addr_t netMask; + ip4_addr_t gateWay; + + ret = netifapi_netif_get_addr(netif_node, &ipAddr, &netMask, &gateWay); + if (ret == 0) { + ip = ip4_addr_get_u32(&ipAddr); + GetIpString(ip, buff, size); + return 0; + } + return -1; +} + +static void SendLocalIp(int sockfd, int code) +{ + char ip[BUF_SHORT_SIZE] = {0}; + + if (code == REQUEST_OK) { + if (DeviceGetIp(ip, sizeof(ip)) < 0) { + LOG_E("get local ip failed! \n"); + return; + } + } + + json_pobject json = create_json_object(); + json_pobject obj = add_number_to_object(json, "code", code); + json_pobject obj1, obj2; + + if (code != REQUEST_OK) { + obj1 = add_string_to_object(json, "errmsg", "connect wifi failed!"); + obj1 = add_object_to_object(json, "result"); + } else { + obj1 = add_object_to_object(json, "result"); + obj2 = add_number_to_object(obj1, "cmd", CMD_CONFIG); + obj2 = add_string_to_object(obj1, "ip", (const char *)ip); + } + + char *msg = json_to_string(json); + const char *eof = "\r\n"; + LOG_D("send msg : %s \n", msg); + if (send(sockfd, msg, strlen(msg), 0) < 0) { + LOG_E("send failed! errno : %d \n", errno); + return; + } + send(sockfd, eof, strlen(eof), 0); + + delete_json_object(json); +} + +static int NetCfgConnect(const char *ssid, const char *pwd, bool wait) +{ + int timecnt = 0; + int retval = 0; + if (WifiStaStart(NetCfgConnectStatus) < 0) { + LOG_E("wifista_start \n"); + return -1; + } + + if (WifiStaConnect((const char *)ssid, (const char *)pwd) < 0) { + LOG_E("hal_wifi_start_connect \n"); + return -1; + } + + if (wait) { + while (g_netManager.status != NET_STA_CONNECTTED) { + usleep(USLEEP_500MS); + if (++timecnt > CONNECT_TIMEOUT) { + retval = -1; + break; + } + } + } + + return retval; +} + +static int ParseWifiInfo(const char *psr, char *ssid, int sl, char *pwd, int pl) +{ + json_handle json; + json_pobject sub; + + int cmd; + char *ps = NULL; + char *pw = NULL; + + json = parse_json(psr); + if (json == NULL) { + LOG_E("parse_json\n"); + return -1; + } + + cmd = get_json_int(json, CMD_KEY); + if (cmd != CMD_CONFIG) { + LOG_E("CMD TYPE FAILED! cmd=%d \n", cmd); + return -1; + } + + sub = get_json_obj(json, PAR_KEY); + if (sub == NULL) { + LOG_E("get param obj failed! \n"); + free_json(json); + return -1; + } + ps = get_json_string(sub, VAL_KEY); + if (ps == NULL) { + LOG_E("get ssid failed! \n"); + free_json(json); + return -1; + } + + if (strncpy_s(ssid, sl, ps, strlen(ps)) < 0) { + LOG_E("strncpy_s failed! \n"); + free_json(json); + return -1; + } + pw = get_json_string(sub, PWD_KEY); + if (pw != NULL) { + LOG_D("pw=%s\n", pw); + if (strncpy_s(pwd, pl, pw, strlen(pw)) < 0) { + LOG_E("strncpy_s failed! \n"); + free_json(json); + return -1; + } + } + + free_json(json); + return 0; +} + +static int NetCfgGetSocketValue(int sockfd) +{ + char recvbuf[BUF_SHORT_SIZE] = {0}; + struct sockaddr_in addr; + socklen_t len; + int result = -1; + char ssid[SSID_MAX_LEN + 1] = {0}; + char pwd[PWD_MAX_LEN + 1] = {0}; + while (1) { + int readBytes; + len = sizeof(addr); + if (g_netManager.mode != NET_MODE_CONFIG) { + break; + } + if (memset_s(recvbuf, BUF_SHORT_SIZE, 0, BUF_SHORT_SIZE) < 0) { + break; + } + readBytes = recvfrom(sockfd, recvbuf, sizeof(recvbuf), 0, (struct sockaddr *)&addr, &len); + if (readBytes <= 0) { + LOG_E("socket disconnect! \n"); + break; + } + if (ParseWifiInfo((const char*)recvbuf, ssid, sizeof(ssid), pwd, sizeof(pwd)) == 0) { + result = 0; + break; + } + } + if (result != -1) { + int code = REQUEST_OK; + SET_NET_EVENT(NET_STA_CONNECTTING, NET_EVENT_CONNECTTING, NULL); + if (NetCfgConnect(ssid, pwd, true) < 0) { + code = REQUEST_ERR; + WifiStaStop(); + result = -1; + } + + usleep(USLEEP_2000MS); // wait ip ready + SendLocalIp(sockfd, code); + usleep(USLEEP_1000MS); + if (result != -1) { + NetServerStart(); + usleep(USLEEP_100MS); // wait ip ready + SET_NET_EVENT(NET_STA_CONNECTTED, NET_EVENT_CONNECTTED, NULL); + } else { + SET_NET_EVENT(NET_STA_NULL, NET_EVENT_CONN_FAILED, NULL); + } + } + if (memset_s(pwd, sizeof(pwd), 0x00, sizeof(pwd)) < 0) { + return -1; + } + return result; +} + +static int NetCfgSocket(void) +{ + int sockfd; + struct sockaddr_in servaddr; + + if ((sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { + LOG_E("socket error! \n"); + return -1; + } + + memset_s(&servaddr, sizeof(servaddr), 0, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(NET_PORT); + servaddr.sin_addr.s_addr = htonl(INADDR_ANY); + + LOG_D("监听%d端口\n", NET_PORT); + if (bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) { + LOG_E("bind socket! \n"); + close(sockfd); + return -1; + } + + if (listen(sockfd, 1) < 0) { + LOG_E("listen failed! errno = %d \n", errno); + close(sockfd); + return -1; + } + + while (g_netManager.mode == NET_MODE_CONFIG) { + int newfd, retval; + struct sockaddr_in client_addr; + socklen_t length = sizeof(client_addr); + newfd = accept(sockfd, (struct sockaddr *)&client_addr, &length); + LOG_D("new socket connect!\n"); + retval = NetCfgGetSocketValue(newfd); + close(newfd); + + if (retval == 0) { + LOG_D("config network success! \n"); + g_netManager.mode = NET_MODE_STA; + } + } + + close(sockfd); + + return 0; +} + +static void NetCfgStartConfig(void) +{ + SET_NET_EVENT(NET_STA_CONFIG, NET_EVENT_CONFIG, NULL); + WifiStaStop(); + if (SoftApStart(g_apName) < 0) { + LOG_E("start softap failed! \n"); + SET_NET_EVENT(NET_STA_NULL, NET_EVENT_CONFIG_FAIL, NULL); + return; + } + + if (NetCfgSocket() < 0) { + SET_NET_EVENT(NET_STA_NULL, NET_EVENT_CONFIG_FAIL, NULL); + return; + } + + SoftApStop(); +} + +static void *NetCfgTask(void *arg) +{ + (void)arg; + int netCfgMode = NET_STA_NULL; + while (g_netManager.netRun) { + if (netCfgMode == g_netManager.mode && netCfgMode != NET_MODE_STA) { + usleep(USLEEP_1000MS); + continue; + } + if (netCfgMode != g_netManager.mode) { + netCfgMode = g_netManager.mode; + } + switch (netCfgMode) { + case NET_MODE_CONFIG: + NetCfgStartConfig(); + break; + default: + break; + } + usleep(USLEEP_1000MS); + } + + return NULL; +} + +int NetCfgStart(const char *apName, NetManagerEventCallback nEventCallback) +{ + osThreadAttr_t attr; + + if (memset_s(&g_netManager, sizeof(g_netManager), 0x00, sizeof(g_netManager)) < 0) { + LOG_E("memset_s g_netManager \n"); + return -1; + } + + g_netManager.gEventCall = nEventCallback; + g_netManager.netRun = true; + g_netManager.mode = NET_STA_CONFIG; + g_apName = apName; + attr.name = "NetManagerTask"; + attr.attr_bits = 0U; + attr.cb_mem = NULL; + attr.cb_size = 0U; + attr.stack_mem = NULL; + attr.stack_size = NET_TASK_STACK_SIZE; + attr.priority = NET_TASK_PRIO; + + if (osThreadNew((osThreadFunc_t)NetCfgTask, NULL, &attr) == NULL) { + LOG_E("Falied to create NetManagerTask!\n"); + return -1; + } + + return 0; +} + +void NetCfgStop(void) +{ + g_netManager.netRun = false; +} + +void NetCfgSetMode(int mode) +{ + g_netManager.mode = mode; +} + +void NetCfgStartConnect(const char *ssid, const char *pwd) +{ + NetCfgConnect(ssid, pwd, false); +} diff --git a/CompleteApps/SmartKettleDevice/common/netcfg/src/network_manager_service.c b/CompleteApps/SmartKettleDevice/common/netcfg/src/network_manager_service.c new file mode 100644 index 0000000000000000000000000000000000000000..85f2426d17cbde4f0f04a6273388bcea4e144305 --- /dev/null +++ b/CompleteApps/SmartKettleDevice/common/netcfg/src/network_manager_service.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "cmsis_os2.h" +#include "base64.h" +#include "sys/time.h" +#include "sys/socket.h" +#include "errno.h" +#include "netinet/in.h" +#include "lwip/inet.h" +#include "lwip/netdb.h" + +#include "json/jsonutil.h" +#include "ohos_types.h" +#include "common_log.h" +#include "network_server.h" +#include "network_config.h" +#include "defines.h" + +int NetManagerRegister(const char *apName, NetManagerEventCallback nEventCallback) +{ + if (NetServerInit(nEventCallback) < 0) { + LOG_E("NetServerInit \n"); + return -1; + } + + if (NetCfgStart(apName, nEventCallback) < 0) { + LOG_E("NetCfgStart \n"); + NetServerDeinit(); + return -1; + } + + return 0; +} + +void NetManagerUnRegister(void) +{ + NetServerDeinit(); + NetCfgStop(); +} + +void NetManagerSetNetMode(int mode) +{ + NetCfgSetMode(mode); +} + +int NetManagerSendMsg(const char *msg) +{ + return NetServerSendMsg(msg); +} diff --git a/CompleteApps/SmartKettleDevice/common/netcfg/src/network_server.c b/CompleteApps/SmartKettleDevice/common/netcfg/src/network_server.c new file mode 100644 index 0000000000000000000000000000000000000000..7d4540112255e40469f0f27625bd995d5302a7a3 --- /dev/null +++ b/CompleteApps/SmartKettleDevice/common/netcfg/src/network_server.c @@ -0,0 +1,326 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "cmsis_os2.h" +#include "base64.h" +#include "sys/time.h" +#include "sys/socket.h" +#include "errno.h" +#include "common_log.h" +#include "netinet/in.h" +#include "lwip/inet.h" +#include "lwip/netdb.h" +#include "json/jsonutil.h" +#include "network_server.h" +#include "defines.h" + +#define SERVER_PORT 8787 +#define MAX_CONNECT 10 + +typedef struct { + int sockfd[MAX_CONNECT]; + int connAmount; + bool isActive; + bool serRun; + + NetManagerEventCallback g_call; +}NetServerInfo; + +static NetServerInfo g_netServer; + +static int NetServerSend(int fd, const char *msg) +{ + const char *eof = "\r\n"; + if (send(fd, msg, strlen(msg), 0) < 0) { + LOG_E("send failed! errno : %d \n", errno); + return -1; + } + LOG_D("send msg : %s \n", msg); + send(fd, eof, strlen(eof), 0); + + return 0; +} + +static void SendRequest(int sockfd, int code) +{ + json_pobject obj; + json_pobject json = create_json_object(); + + obj = add_number_to_object(json, "code", code); + if (code == REQUEST_OK) { + obj = add_string_to_object(json, "errmsg", ""); + } else { + obj = add_string_to_object(json, "errmsg", "explain params error!"); + } + + char *msg = json_to_string(json); + NetServerSend(sockfd, msg); + delete_json_object(json); +} + +static bool IsSpecialSocket(const char *msg) +{ + char buf[] = {0xff, 0x55, 0xaa, 0x55, 0x00}; + bool result = true; + if (msg == NULL || strlen(msg) < strlen(buf)) { + return false; + } + + for (int i = 0; i < strlen(buf); i++) { + if (msg[i] != buf[i]) { + result = false; + break; + } + } + + return result; +} + +static int ReadHandle(int *sockfd, fd_set *fdSet) +{ + char recvbuf[BUF_SHORT_SIZE] = {0}; + int recvbytes; + int fd = *sockfd; + int errcode = -1; + + recvbytes = recv(fd, recvbuf, sizeof(recvbuf) - 1, 0); + if (recvbytes <= 0) { + LOG_D("socket may quit!\n"); + FD_CLR(fd, fdSet); + close(fd); + *sockfd = -1; + g_netServer.connAmount--; + return -1; + } + + if (g_netServer.sockfd[0] == -1 && IsSpecialSocket(recvbuf)) { + *sockfd = -1; + g_netServer.sockfd[0] = fd; + return 0; + } + + LOG_D("recv msg[%d] : %s \n", recvbytes, recvbuf); + if (g_netServer.g_call) { + errcode = g_netServer.g_call(NET_EVENT_RECV_DATA, recvbuf); + } + + if (errcode == -1) { + errcode = REQUEST_ERR; + } else { + errcode = REQUEST_OK; + } + + SendRequest(fd, errcode); + + return 0; +} + +static void CheckNewSocket(int sockFd, fd_set *fdSet, int *maxFd) +{ + int newfd; + struct sockaddr_in client_addr; + socklen_t sin_size = sizeof(client_addr); + if (FD_ISSET(sockFd, fdSet) == 0) { + return; + } + + newfd = accept(sockFd, (struct sockaddr *)&client_addr, &sin_size); + LOG_D("accept:: sock_fd = %d, newfd = %d\n", sockFd, newfd); + if (newfd < 0) { + LOG_E("accept:\n"); + return; + } + + g_netServer.connAmount++; + + if (g_netServer.connAmount < MAX_CONNECT) { + for (int i = 1; i < MAX_CONNECT; i++) { + if (g_netServer.sockfd[i] == -1) { + g_netServer.sockfd[i] = newfd; + break; + } + } + + if (newfd > *maxFd) { + *maxFd = newfd; + } + } else { + LOG_E("max connections arrive, exit\n"); + close(newfd); + } +} + +static void SocketListen(int sock_fd) +{ + fd_set fdset; + int maxsock; + maxsock = sock_fd; + + while (g_netServer.serRun) { + int ret; + struct timeval tv = {2, 0}; + FD_ZERO(&fdset); + FD_SET(sock_fd, &fdset); + for (int i = 0; i < MAX_CONNECT; i++) { + if (g_netServer.sockfd[i] != -1) { + FD_SET(g_netServer.sockfd[i], &fdset); + } + } + ret = select(maxsock + 1, &fdset, NULL, NULL, &tv); + if (ret <= 0) { + continue; + } + for (int i = 0; i < MAX_CONNECT; i++) { + if (g_netServer.sockfd[i] != -1 && FD_ISSET(g_netServer.sockfd[i], &fdset)) { + LOG_D("g_netServer.sockfd[%d] = %d\n", i, g_netServer.sockfd[i]); + ReadHandle(&g_netServer.sockfd[i], &fdset); + continue; + } + } + + CheckNewSocket(sock_fd, &fdset, &maxsock); + } + for (int i = 0; i < MAX_CONNECT; i++) { + if (g_netServer.sockfd[i] != -1) { + close(g_netServer.sockfd[i]); + g_netServer.sockfd[i] = -1; + } + } +} + +static void StartServer(void) +{ + struct sockaddr_in serv_addr; + int sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (sockfd < 0) { + LOG_E("socket failed! \n"); + g_netServer.serRun = false; + return; + } + + if (memset_s(&serv_addr, sizeof(serv_addr), 0, sizeof(serv_addr)) < 0) { + LOG_E("memset_s faield! \n"); + close(sockfd); + g_netServer.serRun = false; + return; + } + + serv_addr.sin_family = AF_INET; // 使用IPv4地址 + serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); + serv_addr.sin_port = htons(SERVER_PORT); // 端口 + if (bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { + LOG_E("bind failed! errno = %d \n", errno); + g_netServer.serRun = false; + close(sockfd); + return; + } + + if (listen(sockfd, MAX_CONNECT) < 0) { + LOG_E("listen failed! errno = %d \n", errno); + g_netServer.serRun = false; + close(sockfd); + return; + } + + SocketListen(sockfd); + + LOG_D("SOCKET SERVER QUIT! \n"); + + close(sockfd); +} + +static void *NetServerTask(void *param) +{ + while (g_netServer.isActive) { + if (g_netServer.serRun == false) { + usleep(USLEEP_100MS); + continue; + } + + StartServer(); + } + + return NULL; +} + +int NetServerInit(NetManagerEventCallback nEventCallback) +{ + osThreadAttr_t attr; + attr.name = "NetServerTask"; + attr.attr_bits = 0U; + attr.cb_mem = NULL; + attr.cb_size = 0U; + attr.stack_mem = NULL; + attr.stack_size = NETSERVER_TASK_STACK_SIZE; + attr.priority = NETSERVER_TASK_PRIO; + + if (memset_s(&g_netServer, sizeof(g_netServer), 0x00, sizeof(g_netServer)) < 0) { + LOG_E("memset_s failed! \n"); + return -1; + } + for (int i = 0; i < MAX_CONNECT; i++) { + g_netServer.sockfd[i] = -1; + } + g_netServer.isActive = true; + g_netServer.g_call = nEventCallback; + if (osThreadNew((osThreadFunc_t)NetServerTask, NULL, &attr) == NULL) { + LOG_E("Falied to create NetServerTask!\n"); + g_netServer.isActive = false; + return -1; + } + + return 0; +} + +void NetServerDeinit(void) +{ + g_netServer.serRun = false; + for (int i = 0; i < MAX_CONNECT; i++) { + if (g_netServer.sockfd[i] != -1) { + shutdown(g_netServer.sockfd[i], SHUT_RDWR); + g_netServer.sockfd[i] = -1; + } + } + + osDelay(DELAY_200MS); + g_netServer.isActive = false; +} + +void NetServerStart(void) +{ + g_netServer.serRun = true; +} + +void NetServerStop(void) +{ + g_netServer.serRun = false; + osDelay(DELAY_200MS); +} + +bool NetServerIsRun(void) +{ + return g_netServer.serRun; +} + +int NetServerSendMsg(const char *msg) +{ + if (g_netServer.serRun == false || g_netServer.sockfd[0] == -1) { + LOG_E("net server is not run! \n"); + return -1; + } + + return NetServerSend(g_netServer.sockfd[0], msg); +} diff --git a/CompleteApps/SmartKettleDevice/common/netcfg/src/softap.c b/CompleteApps/SmartKettleDevice/common/netcfg/src/softap.c new file mode 100644 index 0000000000000000000000000000000000000000..38f44f1a50d0a8da124ca62d525db0bc1120b253 --- /dev/null +++ b/CompleteApps/SmartKettleDevice/common/netcfg/src/softap.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include "lwip/ip_addr.h" +#include "lwip/netifapi.h" +#include "wifi_hotspot.h" +#include "wifi_hotspot_config.h" +#include "softap.h" +#include "defines.h" + +static void ResetAddr(struct netif *pst_lwip_netif) +{ + ip4_addr_t st_gw; + ip4_addr_t st_ipaddr; + ip4_addr_t st_netmask; + + IP4_ADDR(&st_ipaddr, 0, 0, 0, 0); + IP4_ADDR(&st_gw, 0, 0, 0, 0); + IP4_ADDR(&st_netmask, 0, 0, 0, 0); + + netifapi_netif_set_addr(pst_lwip_netif, &st_ipaddr, &st_netmask, &st_gw); +} + +int SoftApStart(const char *ap_name) +{ + HotspotConfig config = {0}; + ip4_addr_t st_gw; + ip4_addr_t st_ipaddr; + ip4_addr_t st_netmask; + char *apName = ap_name; + char ifname[BUF_SHORT_SIZE] = {0}; + int retval; + + if (IsHotspotActive() == WIFI_HOTSPOT_ACTIVE) { + LOG_E("WIFI_HOTSPOT_ACTIVE \n"); + return -1; + } + if (apName == NULL) { + apName = AP_NAME; + } + if (strcpy_s(config.ssid, sizeof(config.ssid), apName) != 0) { + printf("[sample] strcpy ssid fail.\n"); + return -1; + } + config.securityType = WIFI_SEC_TYPE_OPEN; + retval = SetHotspotConfig((const HotspotConfig *)(&config)); + if (retval != WIFI_SUCCESS) { + LOG_E("SetHotspotConfig \n"); + return -1; + } + + retval = EnableHotspot(); + if (retval != WIFI_SUCCESS) { + LOG_E("EnableHotspot failed! \n"); + return -1; + } + return 0; +} + +void SoftApStop(void) +{ + if (IsHotspotActive() == WIFI_HOTSPOT_NOT_ACTIVE) { + LOG_E("WIFI_HOTSPOT_NOT_ACTIVE \n"); + return; + } + + DisableHotspot(); +} diff --git a/CompleteApps/SmartKettleDevice/common/netcfg/src/wifi_sta.c b/CompleteApps/SmartKettleDevice/common/netcfg/src/wifi_sta.c new file mode 100644 index 0000000000000000000000000000000000000000..81852d56339767e7465c24e1d68da6bf321a2c07 --- /dev/null +++ b/CompleteApps/SmartKettleDevice/common/netcfg/src/wifi_sta.c @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include "lwip/ip_addr.h" +#include "lwip/netifapi.h" +#include "wifi_sta.h" +#include "defines.h" + +#define TEST_CONNECT_RETRY_COUNT 5 + +static WifiEvent g_staEventHandler = {0}; +static WifiChangeEvent g_wifiChange = NULL; +static int g_connectRetryCount = 0; + +static void WifiConnectionChangedHandler(int state, WifiLinkedInfo *info) +{ + if (state == WIFI_STATE_AVALIABLE) { + LOG_I("WiFi: Connected.\n"); + g_connectRetryCount = 0; + } else if (state == WIFI_STATE_NOT_AVALIABLE) { + LOG_I("WiFi: Disconnected retry = %d, reason = %d\n", g_connectRetryCount, info->disconnectedReason); + if (g_connectRetryCount < TEST_CONNECT_RETRY_COUNT) { + g_connectRetryCount++; + return; + } + } + if (g_wifiChange) { + g_wifiChange(state); + } +} + +int WifiStaStart(WifiChangeEvent WifiChange) +{ + WifiErrorCode error; + + g_wifiChange = WifiChange; + + if (IsWifiActive() == WIFI_STA_ACTIVE) { + LOG_E("the wifi has been enabled! \n"); + return 1; + } + + error = EnableWifi(); + if (error != WIFI_SUCCESS) { + LOG_E("EnableWifi failed! \n"); + return -1; + } + + g_staEventHandler.OnWifiConnectionChanged = WifiConnectionChangedHandler; + error = RegisterWifiEvent(&g_staEventHandler); + if (error != WIFI_SUCCESS) { + LOG_E("RegisterWifiEvent fail, error = %d\n", error); + return -1; + } + + if (IsWifiActive() == WIFI_STA_NOT_ACTIVE) { + LOG_E("Wifi station is not actived.\n"); + return -1; + } + + return 0; +} + +int WifiStaConnect(const char *ssid, const char *pwd) +{ + WifiDeviceConfig config = {0}; + int netId = 0; + WifiErrorCode error; + + if (ssid == NULL) { + LOG_E("NULL POINT! \n"); + return -1; + } + if (strcpy_s(config.ssid, sizeof(config.ssid), ssid) < 0) { + LOG_E("strcpy_s! \n"); + return -1; + } + + config.ipType = DHCP; + if (pwd == NULL || strlen(pwd) == 0) { + config.securityType = WIFI_SEC_TYPE_OPEN; + } else { + config.securityType = WIFI_SEC_TYPE_PSK; + if (strcpy_s(config.preSharedKey, sizeof(config.preSharedKey), pwd) < 0) { + LOG_E("strcpy_s! \n"); + return -1; + } + } + + error = AddDeviceConfig(&config, &netId); + if (error != WIFI_SUCCESS) { + LOG_E("AddDeviceConfig! \n"); + return -1; + } + + error = ConnectTo(netId); + if (error != WIFI_SUCCESS) { + LOG_E("ConnectTo! \n"); + return -1; + } + + return 0; +} + +void WifiStaStop(void) +{ + if (IsWifiActive() == WIFI_STA_NOT_ACTIVE) { + LOG_E("Wifi station is not actived.\n"); + return; + } + + DisableWifi(); + UnRegisterWifiEvent(&g_staEventHandler); +} + diff --git a/CompleteApps/SmartKettleDevice/kettle/BUILD.gn b/CompleteApps/SmartKettleDevice/kettle/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..5a067c02ca4ab944e6c2d8f70a91d67451861be3 --- /dev/null +++ b/CompleteApps/SmartKettleDevice/kettle/BUILD.gn @@ -0,0 +1,36 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +static_library("kettle") { + sources = [ + "src/kettle_button.c", + "src/kettle_common_init.c", + "src/kettle_heating_sys.c", + "src/kettle_main.c", + "src/kettle_oled.c", + "src/kettle_temp_sensor.c" + ] + + include_dirs = [ + "//applications/sample/wifi-iot/app/kettle/include", + "//applications/sample/wifi-iot/app/common/include", + "//base/iot_hardware/peripheral/interfaces/kits", + "//base/security/deviceauth/frameworks/deviceauth_lite/source", + "//foundation/communication/wifi_lite/interfaces/wifiservice", + "//kernel/liteos_m/kal/cmsis", + "//third_party/mbedtls/include/mbedtls", + "//utils/native/lite/include", + "//device/hisilicon/hispark_pegasus/sdk_liteos/third_party/lwip_sack/include", + "//device/hisilicon/hispark_pegasus/sdk_liteos/platform/os/Huawei_LiteOS/components/lib/libsec/include", + ] +} \ No newline at end of file diff --git a/CompleteApps/SmartKettleDevice/kettle/include/kettle_button.h b/CompleteApps/SmartKettleDevice/kettle/include/kettle_button.h new file mode 100644 index 0000000000000000000000000000000000000000..587552c92bbd90a9895b4415a88898c3fe148ccb --- /dev/null +++ b/CompleteApps/SmartKettleDevice/kettle/include/kettle_button.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __KETTLE_BUTTON_H__ +#define __KETTLE_BUTTON_H__ + +typedef enum { + KEY_0, + KEY_1, + KEY_2, + KEY_3, + KEY_4, + KEY_5, + KEY_6, +}KEY_CODE; + +typedef struct { + int keycode; + int keyvalue; +}KeyEvent; + +typedef void (*KeyEventCallback)(KeyEvent *event); + +/** + * @brief Setting the param of button gpio. + * + * @since 1.0 + * @version 1.0 + */ +void ButtonInit(void); + +/** + * @brief Register the buttion interrupt. + * + * @param eventCall + * @since 1.0 + * @version 1.0 + */ +void RegButtonIrq(KeyEventCallback eventCall); + +#endif // __KETTLE_BUTTON_H__ \ No newline at end of file diff --git a/CompleteApps/SmartKettleDevice/kettle/include/kettle_code_tab.h b/CompleteApps/SmartKettleDevice/kettle/include/kettle_code_tab.h new file mode 100644 index 0000000000000000000000000000000000000000..dbd9bcf0d894414702955cf1224e6e67d89608cf --- /dev/null +++ b/CompleteApps/SmartKettleDevice/kettle/include/kettle_code_tab.h @@ -0,0 +1,357 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __KETTLE_CODE_TAB_H__ +#define __KETTLE_CODE_TAB_H__ + +/* **************************16*16******** */ +const unsigned char F16X16[] = { + 0x10, 0x60, 0x02, 0x8C, 0x00, 0x00, 0xFE, 0x92, 0x92, 0x92, 0x92, 0x92, 0xFE, 0x00, 0x00, 0x00, + 0x04, 0x04, 0x7E, 0x01, 0x40, 0x7E, 0x42, 0x42, 0x7E, 0x42, 0x7E, 0x42, 0x42, 0x7E, 0x40, 0x00, /* "温", 0 */ + 0x10, 0x60, 0x02, 0x8C, 0x00, 0xFE, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0xFE, 0x00, 0x00, 0x00, + 0x04, 0x04, 0x7E, 0x01, 0x44, 0x48, 0x50, 0x7F, 0x40, 0x40, 0x7F, 0x50, 0x48, 0x44, 0x40, 0x00, /* "湿", 1 */ + 0x00, 0x00, 0xFC, 0x24, 0x24, 0x24, 0xFC, 0x25, 0x26, 0x24, 0xFC, 0x24, 0x24, 0x24, 0x04, 0x00, + 0x40, 0x30, 0x8F, 0x80, 0x84, 0x4C, 0x55, 0x25, 0x25, 0x25, 0x55, 0x4C, 0x80, 0x80, 0x80, 0x00, /* "度", 2 */ +}; + +const unsigned char HZ_F16X16[][2][16] = { + { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} + }, /* " ", 0 */ + { + {0x80, 0x82, 0x82, 0x82, 0xFE, 0x82, 0x82, 0x82, 0x82, 0x82, 0xFE, 0x82, 0x82, 0x82, 0x80, 0x00}, + {0x00, 0x80, 0x40, 0x30, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00} + }, /* "开", 1 */ + { + {0x00, 0x20, 0x20, 0x20, 0xA0, 0x60, 0x00, 0xFF, 0x60, 0x80, 0x40, 0x20, 0x18, 0x00, 0x00, 0x00}, + {0x20, 0x10, 0x08, 0x06, 0x01, 0x40, 0x80, 0x7F, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x10, 0x00} + }, /* "水", 2 */ + { + {0x04, 0x04, 0x04, 0x04, 0x9F, 0x44, 0x24, 0x94, 0x24, 0x44, 0x9F, 0x04, 0x04, 0x04, 0x04, 0x00}, + {0x02, 0x02, 0x21, 0x13, 0x0A, 0x42, 0x82, 0x7F, 0x02, 0x02, 0x0A, 0x13, 0x21, 0x02, 0x02, 0x00} + }, /* "茶", 3 */ + { + {0x40, 0x30, 0x0F, 0x88, 0x28, 0x18, 0x08, 0x40, 0x30, 0x0F, 0xC8, 0x08, 0x28, 0x18, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x7F, 0x20, 0x10, 0x88, 0x40, 0x30, 0x0E, 0x01, 0x0E, 0x30, 0x40, 0x80, 0x00} + }, /* "饮", 4 */ + { + {0x00, 0x02, 0x0C, 0xC0, 0x00, 0xF0, 0x10, 0x10, 0x10, 0xFF, 0x10, 0x10, 0x10, 0xF0, 0x00, 0x00}, + {0x02, 0x02, 0x7F, 0x00, 0x00, 0x0F, 0x04, 0x04, 0x04, 0xFF, 0x04, 0x04, 0x04, 0x0F, 0x00, 0x00} + }, /* "冲", 5 */ + { + {0x10, 0x10, 0xF0, 0x1F, 0x10, 0xF0, 0x04, 0x04, 0xFC, 0x04, 0xC4, 0xB4, 0x8C, 0x80, 0x00, 0x00}, + {0x40, 0x22, 0x15, 0x08, 0x16, 0xA1, 0x60, 0x1C, 0x03, 0x00, 0x40, 0x80, 0x40, 0x3F, 0x00, 0x00} + }, /* "奶", 6 */ + { + {0x00, 0x04, 0x04, 0xF4, 0x94, 0x94, 0x94, 0x9F, 0x94, 0x94, 0x94, 0xF4, 0x04, 0x04, 0x00, 0x00}, + {0x40, 0x40, 0x40, 0x7F, 0x4A, 0x4A, 0x4A, 0x4A, 0x4A, 0x4A, 0x4A, 0x7F, 0x40, 0x40, 0x40, 0x00} + }, /* "直", 7 */ + { + {0x40, 0x30, 0x0F, 0x88, 0x28, 0x18, 0x08, 0x40, 0x30, 0x0F, 0xC8, 0x08, 0x28, 0x18, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x7F, 0x20, 0x10, 0x88, 0x40, 0x30, 0x0E, 0x01, 0x0E, 0x30, 0x40, 0x80, 0x00} + }, /* "饮", 8 */ +}; + +const unsigned char HZ_F16X16_1[][2][16] = { + { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} + }, /* " ", 0 */ + { + {0xFC, 0x04, 0x04, 0xFC, 0x10, 0xFF, 0x10, 0x10, 0xF0, 0x00, 0xF8, 0x08, 0x08, 0xF8, 0x00, 0x00}, + {0x0F, 0x04, 0x84, 0x4F, 0x30, 0x0F, 0x40, 0x80, 0x7F, 0x00, 0x7F, 0x20, 0x20, 0x7F, 0x00, 0x00} + }, /* "咖", 1 */ + { + {0xFC, 0x04, 0x04, 0xFC, 0x00, 0x08, 0x88, 0x88, 0xFF, 0x00, 0x00, 0xFF, 0x88, 0x88, 0x08, 0x00}, + {0x0F, 0x04, 0x04, 0x0F, 0x00, 0x08, 0x08, 0x08, 0xFF, 0x00, 0x00, 0xFF, 0x08, 0x08, 0x08, 0x00} + }, /* "啡", 2 */ + { + {0x04, 0x04, 0x04, 0x84, 0x6F, 0x04, 0x04, 0x04, 0xE4, 0x04, 0x8F, 0x44, 0x24, 0x04, 0x04, 0x00}, + {0x04, 0x02, 0x01, 0xFF, 0x00, 0x10, 0x08, 0x04, 0x3F, 0x41, 0x40, 0x40, 0x40, 0x40, 0x78, 0x00} + }, /* "花", 3 */ + { + {0x40, 0x44, 0x54, 0x54, 0x55, 0x56, 0xD4, 0x7C, 0x54, 0x56, 0x55, 0x54, 0x54, 0x44, 0x40, 0x00}, + {0x02, 0x82, 0x82, 0x9A, 0x56, 0x53, 0x22, 0x22, 0x22, 0x52, 0x4E, 0x42, 0x82, 0x02, 0x02, 0x00} + }, /* "姜", 4 */ + { + {0x04, 0x04, 0x04, 0x04, 0x9F, 0x44, 0x24, 0x94, 0x24, 0x44, 0x9F, 0x04, 0x04, 0x04, 0x04, 0x00}, + {0x02, 0x02, 0x21, 0x13, 0x0A, 0x42, 0x82, 0x7F, 0x02, 0x02, 0x0A, 0x13, 0x21, 0x02, 0x02, 0x00} + }, /* "茶", 5 */ +}; + +/* ***********************************6*8*********************************** */ +const unsigned char F6X8[][6] = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // sp + {0x00, 0x00, 0x00, 0x2f, 0x00, 0x00}, // ! + {0x00, 0x00, 0x07, 0x00, 0x07, 0x00}, // " + {0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14}, // # + {0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12}, // $ + {0x00, 0x62, 0x64, 0x08, 0x13, 0x23}, // % + {0x00, 0x36, 0x49, 0x55, 0x22, 0x50}, // & + {0x00, 0x00, 0x05, 0x03, 0x00, 0x00}, // ' + {0x00, 0x00, 0x1c, 0x22, 0x41, 0x00}, // ( + {0x00, 0x00, 0x41, 0x22, 0x1c, 0x00}, // ) + {0x00, 0x14, 0x08, 0x3E, 0x08, 0x14}, // * + {0x00, 0x08, 0x08, 0x3E, 0x08, 0x08}, // + + {0x00, 0x00, 0x00, 0xA0, 0x60, 0x00}, // ,1 + {0x00, 0x08, 0x08, 0x08, 0x08, 0x08}, // - + {0x00, 0x00, 0x60, 0x60, 0x00, 0x00}, // . + {0x00, 0x20, 0x10, 0x08, 0x04, 0x02}, // / + {0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E}, // 0 + {0x00, 0x00, 0x42, 0x7F, 0x40, 0x00}, // 1 + {0x00, 0x42, 0x61, 0x51, 0x49, 0x46}, // 2 + {0x00, 0x21, 0x41, 0x45, 0x4B, 0x31}, // 3 + {0x00, 0x18, 0x14, 0x12, 0x7F, 0x10}, // 4 + {0x00, 0x27, 0x45, 0x45, 0x45, 0x39}, // 5 + {0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30}, // 6 + {0x00, 0x01, 0x71, 0x09, 0x05, 0x03}, // 7 + {0x00, 0x36, 0x49, 0x49, 0x49, 0x36}, // 8 + {0x00, 0x06, 0x49, 0x49, 0x29, 0x1E}, // 9 + {0x00, 0x00, 0x36, 0x36, 0x00, 0x00}, // : + {0x00, 0x00, 0x56, 0x36, 0x00, 0x00}, // ; + {0x00, 0x08, 0x14, 0x22, 0x41, 0x00}, // < + {0x00, 0x14, 0x14, 0x14, 0x14, 0x14}, // = + {0x00, 0x00, 0x41, 0x22, 0x14, 0x08}, // > + {0x00, 0x02, 0x01, 0x51, 0x09, 0x06}, // ? + {0x00, 0x32, 0x49, 0x59, 0x51, 0x3E}, // @ + {0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C}, // A + {0x00, 0x7F, 0x49, 0x49, 0x49, 0x36}, // B + {0x00, 0x3E, 0x41, 0x41, 0x41, 0x22}, // C + {0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C}, // D + {0x00, 0x7F, 0x49, 0x49, 0x49, 0x41}, // E + {0x00, 0x7F, 0x09, 0x09, 0x09, 0x01}, // F + {0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A}, // G + {0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F}, // H + {0x00, 0x00, 0x41, 0x7F, 0x41, 0x00}, // I + {0x00, 0x20, 0x40, 0x41, 0x3F, 0x01}, // J + {0x00, 0x7F, 0x08, 0x14, 0x22, 0x41}, // K + {0x00, 0x7F, 0x40, 0x40, 0x40, 0x40}, // L + {0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F}, // M + {0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F}, // N + {0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E}, // O + {0x00, 0x7F, 0x09, 0x09, 0x09, 0x06}, // P + {0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E}, // Q + {0x00, 0x7F, 0x09, 0x19, 0x29, 0x46}, // R + {0x00, 0x46, 0x49, 0x49, 0x49, 0x31}, // S + {0x00, 0x01, 0x01, 0x7F, 0x01, 0x01}, // T + {0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F}, // U + {0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F}, // V + {0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F}, // W + {0x00, 0x63, 0x14, 0x08, 0x14, 0x63}, // X + {0x00, 0x07, 0x08, 0x70, 0x08, 0x07}, // Y + {0x00, 0x61, 0x51, 0x49, 0x45, 0x43}, // Z + {0x00, 0x00, 0x7F, 0x41, 0x41, 0x00}, // [ + {0x00, 0x55, 0x2A, 0x55, 0x2A, 0x55}, // 55 + {0x00, 0x00, 0x41, 0x41, 0x7F, 0x00}, // ] + {0x00, 0x04, 0x02, 0x01, 0x02, 0x04}, // ^ + {0x00, 0x40, 0x40, 0x40, 0x40, 0x40}, // _ + {0x00, 0x00, 0x01, 0x02, 0x04, 0x00}, // ' + {0x00, 0x20, 0x54, 0x54, 0x54, 0x78}, // a + {0x00, 0x7F, 0x48, 0x44, 0x44, 0x38}, // b + {0x00, 0x38, 0x44, 0x44, 0x44, 0x20}, // c + {0x00, 0x38, 0x44, 0x44, 0x48, 0x7F}, // d + {0x00, 0x38, 0x54, 0x54, 0x54, 0x18}, // e + {0x00, 0x08, 0x7E, 0x09, 0x01, 0x02}, // f + {0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C}, // g + {0x00, 0x7F, 0x08, 0x04, 0x04, 0x78}, // h + {0x00, 0x00, 0x44, 0x7D, 0x40, 0x00}, // i + {0x00, 0x40, 0x80, 0x84, 0x7D, 0x00}, // j + {0x00, 0x7F, 0x10, 0x28, 0x44, 0x00}, // k + {0x00, 0x00, 0x41, 0x7F, 0x40, 0x00}, // l + {0x00, 0x7C, 0x04, 0x18, 0x04, 0x78}, // m + {0x00, 0x7C, 0x08, 0x04, 0x04, 0x78}, // n + {0x00, 0x38, 0x44, 0x44, 0x44, 0x38}, // o + {0x00, 0xFC, 0x24, 0x24, 0x24, 0x18}, // p + {0x00, 0x18, 0x24, 0x24, 0x18, 0xFC}, // q + {0x00, 0x7C, 0x08, 0x04, 0x04, 0x08}, // r + {0x00, 0x48, 0x54, 0x54, 0x54, 0x20}, // s + {0x00, 0x04, 0x3F, 0x44, 0x40, 0x20}, // t + {0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C}, // u + {0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C}, // v + {0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C}, // w + {0x00, 0x44, 0x28, 0x10, 0x28, 0x44}, // x + {0x00, 0x1C, 0xA0, 0xA0, 0xA0, 0x7C}, // y + {0x00, 0x44, 0x64, 0x54, 0x4C, 0x44}, // z + {0x14, 0x14, 0x14, 0x14, 0x14, 0x14}, // horiz lines +}; + +/* ***************************************8*16*********************************** */ +const unsigned char F8X16[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0 + 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x30, 0x00, 0x00, 0x00, // !1 + 0x00, 0x10, 0x0C, 0x06, 0x10, 0x0C, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // "2 + 0x40, 0xC0, 0x78, 0x40, 0xC0, 0x78, 0x40, 0x00, 0x04, 0x3F, 0x04, 0x04, 0x3F, 0x04, 0x04, 0x00, // #3 + 0x00, 0x70, 0x88, 0xFC, 0x08, 0x30, 0x00, 0x00, 0x00, 0x18, 0x20, 0xFF, 0x21, 0x1E, 0x00, 0x00, // $4 + 0xF0, 0x08, 0xF0, 0x00, 0xE0, 0x18, 0x00, 0x00, 0x00, 0x21, 0x1C, 0x03, 0x1E, 0x21, 0x1E, 0x00, // %5 + 0x00, 0xF0, 0x08, 0x88, 0x70, 0x00, 0x00, 0x00, 0x1E, 0x21, 0x23, 0x24, 0x19, 0x27, 0x21, 0x10, // &6 + 0x10, 0x16, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // '7 + 0x00, 0x00, 0x00, 0xE0, 0x18, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x07, 0x18, 0x20, 0x40, 0x00, // (8 + 0x00, 0x02, 0x04, 0x18, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x40, 0x20, 0x18, 0x07, 0x00, 0x00, 0x00, // )9 + 0x40, 0x40, 0x80, 0xF0, 0x80, 0x40, 0x40, 0x00, 0x02, 0x02, 0x01, 0x0F, 0x01, 0x02, 0x02, 0x00, // *10 + 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x1F, 0x01, 0x01, 0x01, 0x00, // +11 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xB0, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, // ,12 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // -13 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, // .14 + 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x18, 0x04, 0x00, 0x60, 0x18, 0x06, 0x01, 0x00, 0x00, 0x00, // 15 + 0x00, 0xE0, 0x10, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x00, 0x0F, 0x10, 0x20, 0x20, 0x10, 0x0F, 0x00, // 0 16 + 0x00, 0x10, 0x10, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // 1 17 + 0x00, 0x70, 0x08, 0x08, 0x08, 0x88, 0x70, 0x00, 0x00, 0x30, 0x28, 0x24, 0x22, 0x21, 0x30, 0x00, // 2 18 + 0x00, 0x30, 0x08, 0x88, 0x88, 0x48, 0x30, 0x00, 0x00, 0x18, 0x20, 0x20, 0x20, 0x11, 0x0E, 0x00, // 3 19 + 0x00, 0x00, 0xC0, 0x20, 0x10, 0xF8, 0x00, 0x00, 0x00, 0x07, 0x04, 0x24, 0x24, 0x3F, 0x24, 0x00, // 4 20 + 0x00, 0xF8, 0x08, 0x88, 0x88, 0x08, 0x08, 0x00, 0x00, 0x19, 0x21, 0x20, 0x20, 0x11, 0x0E, 0x00, // 5 21 + 0x00, 0xE0, 0x10, 0x88, 0x88, 0x18, 0x00, 0x00, 0x00, 0x0F, 0x11, 0x20, 0x20, 0x11, 0x0E, 0x00, // 6 22 + 0x00, 0x38, 0x08, 0x08, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00, // 7 23 + 0x00, 0x70, 0x88, 0x08, 0x08, 0x88, 0x70, 0x00, 0x00, 0x1C, 0x22, 0x21, 0x21, 0x22, 0x1C, 0x00, // 8 24 + 0x00, 0xE0, 0x10, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x00, 0x00, 0x31, 0x22, 0x22, 0x11, 0x0F, 0x00, // 9 25 + 0x00, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, // : 26 + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x00, 0x00, 0x00, 0x00, // ; 27 + 0x00, 0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x00, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00, // < 28 + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, // = 29 + 0x00, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, // > 30 + 0x00, 0x70, 0x48, 0x08, 0x08, 0x08, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x30, 0x36, 0x01, 0x00, 0x00, // ? 31 + 0xC0, 0x30, 0xC8, 0x28, 0xE8, 0x10, 0xE0, 0x00, 0x07, 0x18, 0x27, 0x24, 0x23, 0x14, 0x0B, 0x00, // @ 32 + 0x00, 0x00, 0xC0, 0x38, 0xE0, 0x00, 0x00, 0x00, 0x20, 0x3C, 0x23, 0x02, 0x02, 0x27, 0x38, 0x20, // A 33 + 0x08, 0xF8, 0x88, 0x88, 0x88, 0x70, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x11, 0x0E, 0x00, // B 34 + 0xC0, 0x30, 0x08, 0x08, 0x08, 0x08, 0x38, 0x00, 0x07, 0x18, 0x20, 0x20, 0x20, 0x10, 0x08, 0x00, // C 35 + 0x08, 0xF8, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x10, 0x0F, 0x00, // D 36 + 0x08, 0xF8, 0x88, 0x88, 0xE8, 0x08, 0x10, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x23, 0x20, 0x18, 0x00, // E 37 + 0x08, 0xF8, 0x88, 0x88, 0xE8, 0x08, 0x10, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00, // F 38 + 0xC0, 0x30, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00, 0x07, 0x18, 0x20, 0x20, 0x22, 0x1E, 0x02, 0x00, // G 39 + 0x08, 0xF8, 0x08, 0x00, 0x00, 0x08, 0xF8, 0x08, 0x20, 0x3F, 0x21, 0x01, 0x01, 0x21, 0x3F, 0x20, // H 40 + 0x00, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // I 41 + 0x00, 0x00, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x00, 0xC0, 0x80, 0x80, 0x80, 0x7F, 0x00, 0x00, 0x00, // J 42 + 0x08, 0xF8, 0x88, 0xC0, 0x28, 0x18, 0x08, 0x00, 0x20, 0x3F, 0x20, 0x01, 0x26, 0x38, 0x20, 0x00, // K 43 + 0x08, 0xF8, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x20, 0x30, 0x00, // L 44 + 0x08, 0xF8, 0xF8, 0x00, 0xF8, 0xF8, 0x08, 0x00, 0x20, 0x3F, 0x00, 0x3F, 0x00, 0x3F, 0x20, 0x00, // M 45 + 0x08, 0xF8, 0x30, 0xC0, 0x00, 0x08, 0xF8, 0x08, 0x20, 0x3F, 0x20, 0x00, 0x07, 0x18, 0x3F, 0x00, // N 46 + 0xE0, 0x10, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x0F, 0x10, 0x20, 0x20, 0x20, 0x10, 0x0F, 0x00, // O 47 + 0x08, 0xF8, 0x08, 0x08, 0x08, 0x08, 0xF0, 0x00, 0x20, 0x3F, 0x21, 0x01, 0x01, 0x01, 0x00, 0x00, // P 48 + 0xE0, 0x10, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x0F, 0x18, 0x24, 0x24, 0x38, 0x50, 0x4F, 0x00, // Q 49 + 0x08, 0xF8, 0x88, 0x88, 0x88, 0x88, 0x70, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x03, 0x0C, 0x30, 0x20, // R 50 + 0x00, 0x70, 0x88, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00, 0x38, 0x20, 0x21, 0x21, 0x22, 0x1C, 0x00, // S 51 + 0x18, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x18, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x00, 0x00, // T 52 + 0x08, 0xF8, 0x08, 0x00, 0x00, 0x08, 0xF8, 0x08, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x20, 0x1F, 0x00, // U 53 + 0x08, 0x78, 0x88, 0x00, 0x00, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x07, 0x38, 0x0E, 0x01, 0x00, 0x00, // V 54 + 0xF8, 0x08, 0x00, 0xF8, 0x00, 0x08, 0xF8, 0x00, 0x03, 0x3C, 0x07, 0x00, 0x07, 0x3C, 0x03, 0x00, // W 55 + 0x08, 0x18, 0x68, 0x80, 0x80, 0x68, 0x18, 0x08, 0x20, 0x30, 0x2C, 0x03, 0x03, 0x2C, 0x30, 0x20, // X 56 + 0x08, 0x38, 0xC8, 0x00, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x00, 0x00, // Y 57 + 0x10, 0x08, 0x08, 0x08, 0xC8, 0x38, 0x08, 0x00, 0x20, 0x38, 0x26, 0x21, 0x20, 0x20, 0x18, 0x00, // Z 58 + 0x00, 0x00, 0x00, 0xFE, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x40, 0x40, 0x40, 0x00, // [ 59 + 0x00, 0x0C, 0x30, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x38, 0xC0, 0x00, // \ 60 + 0x00, 0x02, 0x02, 0x02, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x7F, 0x00, 0x00, 0x00, // ] 61 + 0x00, 0x00, 0x04, 0x02, 0x02, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ^ 62 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // _ 63 + 0x00, 0x02, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ` 64 + 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x19, 0x24, 0x22, 0x22, 0x22, 0x3F, 0x20, // a 65 + 0x08, 0xF8, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x11, 0x20, 0x20, 0x11, 0x0E, 0x00, // b 66 + 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0x20, 0x11, 0x00, // c 67 + 0x00, 0x00, 0x00, 0x80, 0x80, 0x88, 0xF8, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0x10, 0x3F, 0x20, // d 68 + 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x22, 0x22, 0x22, 0x13, 0x00, // e 69 + 0x00, 0x80, 0x80, 0xF0, 0x88, 0x88, 0x88, 0x18, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // f 70 + 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x6B, 0x94, 0x94, 0x94, 0x93, 0x60, 0x00, // g 71 + 0x08, 0xF8, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x3F, 0x21, 0x00, 0x00, 0x20, 0x3F, 0x20, // h 72 + 0x00, 0x80, 0x98, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // i 73 + 0x00, 0x00, 0x00, 0x80, 0x98, 0x98, 0x00, 0x00, 0x00, 0xC0, 0x80, 0x80, 0x80, 0x7F, 0x00, 0x00, // j 74 + 0x08, 0xF8, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x20, 0x3F, 0x24, 0x02, 0x2D, 0x30, 0x20, 0x00, // k 75 + 0x00, 0x08, 0x08, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // l 76 + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x3F, 0x20, 0x00, 0x3F, // m 77 + 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x3F, 0x21, 0x00, 0x00, 0x20, 0x3F, 0x20, // n 78 + 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x20, 0x1F, 0x00, // o 79 + 0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0xFF, 0xA1, 0x20, 0x20, 0x11, 0x0E, 0x00, // p 80 + 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0xA0, 0xFF, 0x80, // q 81 + 0x80, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x20, 0x20, 0x3F, 0x21, 0x20, 0x00, 0x01, 0x00, // r 82 + 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x33, 0x24, 0x24, 0x24, 0x24, 0x19, 0x00, // s 83 + 0x00, 0x80, 0x80, 0xE0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x00, 0x00, // t 84 + 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x10, 0x3F, 0x20, // u 85 + 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x01, 0x0E, 0x30, 0x08, 0x06, 0x01, 0x00, // v 86 + 0x80, 0x80, 0x00, 0x80, 0x00, 0x80, 0x80, 0x80, 0x0F, 0x30, 0x0C, 0x03, 0x0C, 0x30, 0x0F, 0x00, // w 87 + 0x00, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x31, 0x2E, 0x0E, 0x31, 0x20, 0x00, // x 88 + 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x81, 0x8E, 0x70, 0x18, 0x06, 0x01, 0x00, // y 89 + 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x21, 0x30, 0x2C, 0x22, 0x21, 0x30, 0x00, // z 90 + 0x00, 0x00, 0x00, 0x00, 0x80, 0x7C, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x40, 0x40, // { 91 + 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, // | 92 + 0x00, 0x02, 0x02, 0x7C, 0x80, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x3F, 0x00, 0x00, 0x00, 0x00, // } 93 + 0x00, 0x06, 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ~ 94 +}; + +const unsigned char BMP1[] = { + 0x00, 0x03, 0x05, 0x09, 0x11, 0xFF, 0x11, 0x89, 0x05, 0xC3, 0x00, 0xE0, 0x00, 0xF0, 0x00, 0xF8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x28, 0xFF, 0x11, 0xAA, 0x44, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x01, 0x38, 0x44, 0x82, 0x92, + 0x92, 0x74, 0x01, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x44, 0xC7, 0x01, 0x7D, + 0x7D, 0x7D, 0x7D, 0x01, 0x7D, 0x7D, 0x7D, 0x7D, 0x01, 0x7D, 0x7D, 0x7D, 0x7D, 0x01, 0xFF, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, + 0x6D, 0x6D, 0x6D, 0x6D, 0x6D, 0x00, 0x00, 0x60, 0x60, 0x60, 0x60, 0x60, 0x00, 0x00, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0x00, 0x00, + 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0x00, 0x00, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0x00, 0x00, 0xDB, 0xDB, + 0xDB, 0xDB, 0xDB, 0x00, 0x00, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0x00, 0x00, 0xD8, 0xD8, 0xD8, 0xD8, + 0xD8, 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, + 0x00, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x00, 0x00, 0x06, 0x06, 0x06, 0xE6, 0x66, 0x20, 0x00, 0x06, 0x06, 0x86, 0x06, + 0x06, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x86, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x00, + 0x00, 0x86, 0x86, 0x86, 0x86, 0x86, 0x80, 0x80, 0x86, 0x86, 0x06, 0x86, 0x86, 0xC0, 0xC0, 0x86, + 0x86, 0x86, 0x06, 0x06, 0xD0, 0x30, 0x76, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x1C, 0x00, 0xFE, 0x00, 0x01, + 0x02, 0x00, 0xC4, 0x18, 0x20, 0x02, 0x9E, 0x63, 0xB2, 0x0E, 0x00, 0xFF, 0x81, 0x81, 0xFF, 0x00, + 0x00, 0x80, 0x40, 0x30, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x23, 0xEA, 0xAA, 0xBF, 0xAA, + 0xEA, 0x03, 0x3F, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x0C, 0x08, 0x00, 0x00, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x81, 0x80, 0x80, 0x81, 0x80, + 0x81, 0x80, 0x80, 0x80, 0x80, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x01, 0x01, 0x09, 0x0C, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, + 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, + 0x00, 0x1E, 0x21, 0x40, 0x40, 0x50, 0x21, 0x5E, 0x00, 0x1E, 0x21, 0x40, 0x40, 0x50, 0x21, 0x5E, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xC1, 0xC1, 0xFF, + 0xFF, 0xC1, 0xC1, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0xFC, 0xF3, 0xEF, 0xF3, 0xFC, + 0x80, 0xFF, 0x80, 0xEE, 0xEE, 0xEE, 0xF5, 0xFB, 0xFF, 0x9C, 0xBE, 0xB6, 0xB6, 0x88, 0xFF, 0x00, + /* MP3_UI.bmp */ +}; +#endif // __KETTLE_CODE_TAB_H__ diff --git a/CompleteApps/SmartKettleDevice/kettle/include/kettle_common_init.h b/CompleteApps/SmartKettleDevice/kettle/include/kettle_common_init.h new file mode 100644 index 0000000000000000000000000000000000000000..57cef077eca44c031dff0b4a67cb822810e51e88 --- /dev/null +++ b/CompleteApps/SmartKettleDevice/kettle/include/kettle_common_init.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __KETTLE_COMMON_INIT_H__ +#define __KETTLE_COMMON_INIT_H__ + +#include +#include "ohos_init.h" +#include "cmsis_os2.h" +#include "securec.h" +#include "ohos_types.h" +#include "iot_gpio.h" +#include "iot_errno.h" +#include "iot_i2c.h" + +/** + * @brief Init the kettle device. Include the button Oled and heating system. + * + * @since 1.0 + * @version 1.0 + */ +void DeviceInit(void); + +#endif /* __KETTLE_COMMON_INIT_H__ */ diff --git a/CompleteApps/SmartKettleDevice/kettle/include/kettle_heating_sys.h b/CompleteApps/SmartKettleDevice/kettle/include/kettle_heating_sys.h new file mode 100644 index 0000000000000000000000000000000000000000..6c7367a5168eee46db972ced7a2ff2dde0894afe --- /dev/null +++ b/CompleteApps/SmartKettleDevice/kettle/include/kettle_heating_sys.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef __KETTLE_HEATING_SYS_H__ +#define __KETTLE_HEATING_SYS_H__ + +typedef enum { + WARM_MODE, // heat the water to the setting temp + BOILED_MODE // heat the water to 100 and then decrease to the setting temp +}HEAT_MODE; + +typedef enum { + HEAT_EVENT_CFG_UPDATE, // the heat sys config has been update + HEAT_EVENT_TEMP_CHANGE, // the temp has been changed + HEAT_EVENT_TIMER_REACH // the setting timer has reached +}HEAT_EVENT_TYPE; + +typedef enum { + STAT_WARMING, + STAT_HEATTING +}HEAT_STATUS; + +typedef struct { + HEAT_EVENT_TYPE eType; + int temp; // current temp + int stat; // current stat, the value reference HEAT_STATUS +}HEAT_EVENT; + +// the config info which set by other process +typedef struct { + unsigned int mode; // work mode + unsigned int temp; // temp to keep + unsigned int times; // keep temp times +} HeatSysCfg; + +/** + * @brief: the heat sys event callback, when the event has been occurrences + * + * @param: event-- reference HEAT_EVENT + * @since 1.0 + * @version 1.0 + */ +typedef int (*HeatEventCallback)(HEAT_EVENT *event); + +/** + * @brief The Heating system Init + * + * @returns 0 success, -1 some error occurrences + * @since 1.0 + * @version 1.0 + */ +int HeatSysInit(void); + +/** + * @brief: register the heat sys + * + * @param callback -- the heat sys event callback + * @return 0 success, -1 some error occurrences, 1--heat sys has been registered + * @since 1.0 + * @version 1.0 + */ +int HeatSysRegister(HeatEventCallback callback); + +/** + * @brief: update the heat sys configs + * + * @param cfg -- heat sys configs, reference HeatSysCfg + * @returns 0 success, -1 some error occurrences + * @since 1.0 + * @version 1.0 + */ +int UpdateHeatSysCfg(HeatSysCfg cfg); + +/** + * @brief Heating system deinit, release the heat sys resource. + * + * @since 1.0 + * @version 1.0 + */ +void HeatSysDeInit(void); + +#endif // __KETTLE_HEATING_SYS_H__ \ No newline at end of file diff --git a/CompleteApps/SmartKettleDevice/kettle/include/kettle_main.h b/CompleteApps/SmartKettleDevice/kettle/include/kettle_main.h new file mode 100644 index 0000000000000000000000000000000000000000..2c3a5df9168b37e2f922e7f7e82e9dcb15d16618 --- /dev/null +++ b/CompleteApps/SmartKettleDevice/kettle/include/kettle_main.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __KETTLE_MAIN_H__ +#define __KETTLE_MAIN_H__ + +#include "kettle_common_init.h" + +#define DRINK_WATER 25 +#define MILK 50 +#define GINGER_TEA 60 +#define SCENTED_TEA 70 +#define TEAS 80 +#define COFFEE 85 +#define BOILED_WATER 99 +#define APP_DEMO_KETTLE_SLEEP_TIME_US 1000000 + +#define X_KETTLE_SHOW_TEMP 24 +#define Y_KETTLE_SHOW_TEMP 2 +#define X_KETTLE_SHOW_DISCRITION 32 +#define Y_KETTLE_SHOW_DISCRITION 5 + +#define KETTLE_TASK_STACK_SIZE (1024*4) +#define KETTLE_TASK_PRIO (25) + +#endif // __KETTLE_MAIN_H__ diff --git a/CompleteApps/SmartKettleDevice/kettle/include/kettle_oled.h b/CompleteApps/SmartKettleDevice/kettle/include/kettle_oled.h new file mode 100644 index 0000000000000000000000000000000000000000..1fa11bb5721f4d6b49b8e460212110f98d7a8fb9 --- /dev/null +++ b/CompleteApps/SmartKettleDevice/kettle/include/kettle_oled.h @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __APP_DEMO_OLED_H__ +#define __APP_DEMO_OLED_H__ + +#include "ohos_types.h" + +#define WIFI_IOT_OLED_I2C_IDX_0 0 +#define WIFI_IOT_IO_FUNC_GPIO_13_I2C0_SDA 6 +#define WIFI_IOT_IO_FUNC_GPIO_14_I2C0_SCL 6 + +#define I2C_REG_ARRAY_LEN (64) +#define BH_SEND_BUFF (1) +#define OLED_SEND_BUFF_LEN (28) +#define OLED_SEND_BUFF_LEN2 (25) +#define OLED_SEND_BUFF_LEN3 (27) +#define OLED_SEND_BUFF_LEN4 (29) +#define Max_Column (128) +#define OLED_DEMO_TASK_STAK_SIZE (4096) +#define OLED_DEMO_TASK_PRIORITY (25) + +#define OLED_ADDRESS 0x78 +#define OLED_ADDRESS_WRITE_CMD 0x00 +#define OLED_ADDRESS_WRITE_DATA 0x40 + +#define OLED_CLEAN_SCREEN ((uint8)0x00) + +#define SLEEP_20_MS 20000 +#define SLEEP_100_MS 100000 + +#define DELAY_10_MS 1 +#define DELAY_100_MS 10 +#define DELAY_200_MS 20 +#define DELAY_250_MS 25 +#define DELAY_500_MS 50 +/* ssd1306 register cmd */ +#define DISPLAY_OFF 0xAE +#define SET_LOW_COLUMN_ADDRESS 0x00 +#define SET_HIGH_COLUMN_ADDRESS 0x10 +#define SET_START_LINE_ADDRESS 0x40 +#define SET_PAGE_ADDRESS 0xB0 +#define CONTRACT_CONTROL 0x81 +#define FULL_SCREEN 0xFF +#define SET_SEGMENT_REMAP 0xA1 +#define NORMAL 0xA6 +#define SET_MULTIPLEX 0xA8 +#define DUTY 0x3F +#define SCAN_DIRECTION 0xC8 +#define DISPLAY_OFFSET 0xD3 +#define DISPLAY_TYPE 0x00 +#define OSC_DIVISION 0xD5 +#define DIVISION 0x80 +#define COLOR_MODE_OFF 0xD8 +#define COLOR 0x05 +#define PRE_CHARGE_PERIOD 0xD9 +#define PERIOD 0xF1 +#define PIN_CONFIGUARTION 0xDA +#define CONFIGUARTION 0x12 +#define SET_VCOMH 0xDB +#define VCOMH 0x30 +#define SET_CHARGE_PUMP_ENABLE 0x8D +#define PUMP_ENABLE 0x14 +#define TURN_ON_OLED_PANEL 0xAF +#define CMD_LENGTH 27 + +#define OLED_I2C_WRITE_CMD_SEND_LEN 2 + +#define HORIZONTAL_COORDINATE_OF_SLOGANS 2 +#define VERTICAL_COORDINATE_OF_SLOGANS 3 +#define CHAR_SIZE_OF_LANTTICE_8_16 16 +#define HORI_PIXEL_OF_LANTTICE_8_16 8 + +#define CHAR_SIZE_OF_LANTTICE_HZ_16_16 32 +#define HORI_PIXEL_OF_LANTTICE_HZ_16_16 16 + +#define CHAR_SIZE_OF_LANTTICE_HZ_16_16_1 48 +#define HORI_PIXEL_OF_LANTTICE_HZ_16_16_1 16 +#define HORI_PIXEL_OF_LANTTICE_6_8 6 + +#define LIMIT_HORI_PIXEL 120 +#define MAX_LINE_OF_LANTTICE 8 +#define SET_POSITION_OFFSET 4 +#define MAX_OLED_INIT_CYCLE_TIMES 5 + +/** + * @brief Oled Show str + * + * @param x The offset of X axis + * y The offset of Y axis + * chr The str that you want show + * charSize The CharSize (eg: 8*6) + * @since 1.0 + * @version 1.0 + */ +void OledShowStr(uint8 x, uint8 y, const char *chr, uint8 charSize); + +/** + * @brief Oled Init Operations + * + * @since 1.0 + * @version 1.0 + */ +uint32 OledInit(void); // Init OLED PANEL + +#endif // __KETTLE_OLED_H__ diff --git a/CompleteApps/SmartKettleDevice/kettle/include/kettle_temp_sensor.h b/CompleteApps/SmartKettleDevice/kettle/include/kettle_temp_sensor.h new file mode 100644 index 0000000000000000000000000000000000000000..47e33c10139275428ee1217069540e394e51dbd5 --- /dev/null +++ b/CompleteApps/SmartKettleDevice/kettle/include/kettle_temp_sensor.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef __KETTLE_TEMP_SENSOR_H__ +#define __KETTLE_TEMP_SENSOR_H__ + +#define WIFI_IOT_SENSOR_I2C_IDX_0 (0) +#define AHT_SLEEP_20MS (20000) // 20ms +#define AHT_SLEEP_50MS (50000) // 50ms +#define AHT_SLEEP_1S (1000000) // 1s +#define AHT_DELAY_10MS (1) // 10ms +#define AHT_DELAY_40MS (4) // 40ms +#define AHT_DELAY_100MS (10) // 100ms +#define AHT_DEVICE_ADDR (0x38) // device addr +#define AHT_DEVICE_READ_STATUS (0x71) // befor read tem&humi data need to send cmd to comfir the +#define AHT_DEVICE_INIT_CMD (0xBE) // aht init cmd +#define AHT_DEVICE_TEST_CMD (0xAC) // test cmd +#define AHT_DEVICE_PARAM_HIGH_BYTE (0x33) +#define AHT_DEVICE_PARAM_LOW_BYTE (0x00) +#define AHT_DEVICE_PARAM_INIT_HIGH (0x08) +#define AHT_DEVICE_CALIBRATION (0x80) +#define AHT_DEVICE_CALIBRATION_ERR (0x1C) +#define AHT_DEVICE_CALIBRATION_ERR_R (0x18) +#define AHT_TASK_SLEEP_TIME (20000) // thread sleep 20ms + +typedef enum { + AHT_TEMPERATURE = 1, // TEMP + AHT_HUMIDITY = 2, // HUMI +} aht_serson_type; + +/** + * @brief The sensor init operation + * + * @return If success return WIFI_IOT_SUCCESS. else return WIFI_IOT_FAILURE. + * @since 1.0 + * @version 1.0 + */ +int TempSensorInit(void); + +/** + * @brief Get the temp value of sensor. + * + * @return Return the temp value. + * @since 1.0 + * @version 1.0 + */ +uint32 GetSensorTemp(void); + +#endif // __KETTLE_TEMP_SENSOR_H__ \ No newline at end of file diff --git a/CompleteApps/SmartKettleDevice/kettle/src/kettle_button.c b/CompleteApps/SmartKettleDevice/kettle/src/kettle_button.c new file mode 100644 index 0000000000000000000000000000000000000000..ad7a4a948d18b5daabc1e5a5e69d400382e86747 --- /dev/null +++ b/CompleteApps/SmartKettleDevice/kettle/src/kettle_button.c @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "common_log.h" +#include "kettle_button.h" +#include "iot_gpio.h" +#include "iot_errno.h" +#include "peripheral_hal.h" + +#define WIFI_IOT_GPIO_IDX_5 5 +#define IOT_IO_FUNC_GPIO_5_GPIO 0 + +typedef struct { + KeyEventCallback mEventCall; + int mButtonID; +}KettleButton; + +static KettleButton g_button; +void ButtonIrqCallback(char *param) +{ + LOG_D("Debug for gpio5_irq_callback\n"); + KettleButton *button = (KettleButton *)param; + if (button != NULL && button->mEventCall != NULL) { + KeyEvent e; + e.keycode = button->mButtonID; + e.keyvalue = 1; + button->mEventCall(&e); + } +} + +void ButtonInit(void) +{ + IoTGpioInit(WIFI_IOT_GPIO_IDX_5); + HalIoSetFunc(HAL_WIFI_IOT_IO_NAME_GPIO_5, IOT_IO_FUNC_GPIO_5_GPIO); // Set the gpio5 function + IoTGpioSetDir(WIFI_IOT_GPIO_IDX_5, IOT_GPIO_DIR_IN); // Set gpio dir: in/out +} + +void RegButtonIrq(KeyEventCallback eventCall) +{ + g_button.mEventCall = eventCall; + g_button.mButtonID = KEY_5; + if (IoTGpioRegisterIsrFunc(WIFI_IOT_GPIO_IDX_5, IOT_INT_TYPE_EDGE, IOT_GPIO_EDGE_FALL_LEVEL_LOW, + &ButtonIrqCallback, (char *)(&g_button)) != IOT_SUCCESS) { + LOG_E("Register gpio5 isr failed !\n"); + } +} + diff --git a/CompleteApps/SmartKettleDevice/kettle/src/kettle_common_init.c b/CompleteApps/SmartKettleDevice/kettle/src/kettle_common_init.c new file mode 100644 index 0000000000000000000000000000000000000000..3cfc660847e4392356de88b066bc633ab136fb36 --- /dev/null +++ b/CompleteApps/SmartKettleDevice/kettle/src/kettle_common_init.c @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "common_log.h" +#include "kettle_oled.h" +#include "kettle_button.h" +#include "kettle_common_init.h" +#include "kettle_heating_sys.h" +#include "peripheral_hal.h" + +#define I2C_IDX_BAUDRATE (400000) + +static void I2cBusInit(void) +{ + IoTGpioInit(HAL_WIFI_IOT_IO_NAME_GPIO_13); + HalIoSetFunc(HAL_WIFI_IOT_IO_NAME_GPIO_13, WIFI_IOT_IO_FUNC_GPIO_13_I2C0_SDA); // Set up the gpio funcion as i2c bus + IoTGpioInit(HAL_WIFI_IOT_IO_NAME_GPIO_14); + HalIoSetFunc(HAL_WIFI_IOT_IO_NAME_GPIO_14, WIFI_IOT_IO_FUNC_GPIO_14_I2C0_SCL); + IoTI2cInit(WIFI_IOT_OLED_I2C_IDX_0, I2C_IDX_BAUDRATE); // Rate: 400kbps + LOG_I("I2C0 bus init success !\n"); +} + +void DeviceInit(void) +{ + ButtonInit(); + I2cBusInit(); + while (IOT_SUCCESS != OledInit()) { + LOG_E("Connecting oled board falied! Please access oled board !\n"); + usleep(SLEEP_100_MS); // refer from the datasheet of SSD1306 + } + LOG_I("Oled init success !\n"); + while (IOT_SUCCESS != HeatSysInit()) { + LOG_E("TempSensorCheckAndInit falied !\n"); + usleep(SLEEP_100_MS); // Keep the power supply stable + } + LOG_I("Device init success !\n"); +} \ No newline at end of file diff --git a/CompleteApps/SmartKettleDevice/kettle/src/kettle_heating_sys.c b/CompleteApps/SmartKettleDevice/kettle/src/kettle_heating_sys.c new file mode 100644 index 0000000000000000000000000000000000000000..1ed71a1d9138dca3afe678c44936a7f18efdb43a --- /dev/null +++ b/CompleteApps/SmartKettleDevice/kettle/src/kettle_heating_sys.c @@ -0,0 +1,255 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include "ohos_types.h" +#include "cmsis_os2.h" +#include "securec.h" +#include "common_log.h" +#include "kettle_heating_sys.h" +#include "kettle_temp_sensor.h" + +#define HEAT_DEFAULT_TEMP (60) +#define MAX_HEAT_TEMP (100) +#define TICKS_NUMBER (100) // 1 ticks = 10ms +#ifndef SLEEP_200_MS +#define SLEEP_200_MS (200000) +#endif + +#define HEAT_TASK_STAK_SIZE (1024*4) +#define HEAT_TASK_PRIORITY (30) + +#define SET_HEAT_EVENT(type, temp, stat) ({ \ + if ((gHeatInfo != NULL) && (gHeatInfo->gEventHeatCallback)) { \ + HEAT_EVENT e = {type, temp, stat}; \ + gHeatInfo->gEventHeatCallback(&e); \ + } \ +}) + +typedef struct { + HeatSysCfg cfg; + + bool mUpdateFlag; + bool boiling; + + uint8_t heatStat; + uint8_t timerCount; + uint8_t heatTemp; + osTimerId_t g_kettleTimerId; + + HeatEventCallback gEventHeatCallback; +}HeatInfo; + +static void HeatSysEnableHeat(void) +{ + LOG_I("enable heat"); +} + +static void HeatSysDisableHeat(void) +{ + LOG_I("disable heat"); +} + +void TimerCallBack(void *arg) +{ + HeatInfo *gHeatInfo = (HeatInfo *)arg; + + if ((gHeatInfo != NULL) && (gHeatInfo->timerCount > 0)) { + gHeatInfo->timerCount--; + } +} + +static void HeatStartTimer(HeatInfo *gHeatInfo) +{ + if (gHeatInfo == NULL) { + LOG_E("NULL POINT! \n"); + return; + } + gHeatInfo->g_kettleTimerId = osTimerNew(&TimerCallBack, osTimerPeriodic, gHeatInfo, NULL); + osTimerStart(gHeatInfo->g_kettleTimerId, TICKS_NUMBER); +} + +static void HeatDealTimerEvent(HeatInfo *gHeatInfo) +{ + if (gHeatInfo == NULL) { + LOG_E("NULL POINT! \n"); + return; + } + + osTimerStop(gHeatInfo->g_kettleTimerId); + osTimerDelete(gHeatInfo->g_kettleTimerId); + gHeatInfo->g_kettleTimerId = NULL; + SET_HEAT_EVENT(HEAT_EVENT_TIMER_REACH, gHeatInfo->heatTemp, gHeatInfo->heatStat); +} + +static void HeatSysCheckStatus(HeatInfo *gHeatInfo, unsigned int temp, bool boiled) +{ + // when current temp larger then the setted temp, change the heat status to warm + if (temp >= gHeatInfo->cfg.temp) { + if (boiled && gHeatInfo->heatStat != STAT_WARMING) { + HeatSysDisableHeat(); + gHeatInfo->heatStat = STAT_WARMING; + } + } else { // when current temp less then the setted temp, change the heat status to heat + if (gHeatInfo->heatStat != STAT_HEATTING) { + HeatSysEnableHeat(); + gHeatInfo->heatStat = STAT_HEATTING; + } + } +} + +static void *HeatedTask(const char *param) +{ + LOG_D("HeatedTask enter\n"); + HeatInfo *gHeatInfo = (HeatInfo *)param; + if (gHeatInfo == NULL) { + LOG_E("gHeatInfo POINT NULL! \n"); + return NULL; + } + + gHeatInfo->heatTemp = GetSensorTemp(); + HeatSysEnableHeat(); + bool workingFlag = false; + + while (1) { + uint32_t temp = GetSensorTemp(); + + + if (gHeatInfo->cfg.mode == BOILED_MODE) { + if (temp == MAX_HEAT_TEMP && gHeatInfo->boiling == false) { // mark the temp has been boiled + gHeatInfo->boiling = true; + } + HeatSysCheckStatus(gHeatInfo, temp, gHeatInfo->boiling); + } else { + HeatSysCheckStatus(gHeatInfo, temp, true); + } + + // In the warm status, when the warm time has been setted, start the timer! + if (gHeatInfo->heatStat == STAT_WARMING) { + if (gHeatInfo->g_kettleTimerId == NULL && gHeatInfo->cfg.times > 0) { + gHeatInfo->timerCount = (gHeatInfo->cfg.times * 60 * 60); // timecount = times*60*60 + HeatStartTimer(gHeatInfo); + } + } + + // When the heat cfg has been updated, must notify the main process + if (gHeatInfo->mUpdateFlag == TRUE) { + SET_HEAT_EVENT(HEAT_EVENT_CFG_UPDATE, temp, gHeatInfo->heatStat); + workingFlag = true; + gHeatInfo->mUpdateFlag = false; + usleep(SLEEP_200_MS); // Release CPU resources. + continue; + } + + // If heat preservation time is over, notify the main process. + if ((gHeatInfo->g_kettleTimerId != NULL) && (gHeatInfo->timerCount == 0)) { + HeatDealTimerEvent(gHeatInfo); + usleep(SLEEP_200_MS); // Release CPU resources. + continue; + } + + // The temp has been changed, notify the main process + if ((temp != gHeatInfo->heatTemp) && (workingFlag == true)) { + gHeatInfo->heatTemp = temp; + SET_HEAT_EVENT(HEAT_EVENT_TEMP_CHANGE, temp, gHeatInfo->heatStat); + } + + usleep(SLEEP_200_MS); // Release CPU resources. + } + LOG_D("EXIT HeatedTask \n"); + + return NULL; +} + +static HeatInfo *gHeatInfo = NULL; // the heat info struct +static bool g_sensorInited = false; + +int HeatSysInit(void) +{ + if (g_sensorInited) { + LOG_E("the TempSensor has been inited! \n"); + return 1; + } + + if (TempSensorInit() < 0) { + LOG_E("AHT20SensorInit failed! \n"); + return -1; + } + + g_sensorInited = true; + + return 0; +} + +int HeatSysRegister(HeatEventCallback callback) +{ + // check whether the sensor has been inited! + if (g_sensorInited == false) { + LOG_E("TempSensor has not been inited! must be inited TempSensor before HeatSysRegister! \n"); + return -1; + } + + if (gHeatInfo != NULL) { + LOG_E("HeatSys has been Registered! \n"); + return 1; + } + + gHeatInfo = (HeatInfo *)malloc(sizeof(HeatInfo)); + if (gHeatInfo == NULL) { + LOG_E("OOM! \n"); + return -1; + } + memset_s(gHeatInfo, sizeof(HeatInfo), 0x00, sizeof(HeatInfo)); + gHeatInfo->heatTemp = HEAT_DEFAULT_TEMP; + gHeatInfo->gEventHeatCallback = callback; + + osThreadAttr_t attr = {0}; + attr.name = (char*)"heattask"; + attr.attr_bits = 0U; + attr.cb_mem = NULL; + attr.cb_size = 0U; + attr.stack_mem = NULL; + attr.stack_size = HEAT_TASK_STAK_SIZE; + attr.priority = HEAT_TASK_PRIORITY; + if (osThreadNew((osThreadFunc_t)HeatedTask, gHeatInfo, &attr) == NULL) { + LOG_E("Failed to create HeatedTask !\n"); + } + + return 0; +} + +int UpdateHeatSysCfg(HeatSysCfg cfg) +{ + if (gHeatInfo == NULL) { + LOG_E("HeatSys has not been inited!!!! \n"); + return -1; + } + + gHeatInfo->mUpdateFlag = true; + memcpy_s(&(gHeatInfo->cfg), sizeof(HeatSysCfg), &cfg, sizeof(HeatSysCfg)); + + return 0; +} + +void HeatSysDeInit(void) +{ + if (gHeatInfo != NULL) { + free(gHeatInfo); + gHeatInfo = NULL; + } + g_sensorInited = false; +} diff --git a/CompleteApps/SmartKettleDevice/kettle/src/kettle_main.c b/CompleteApps/SmartKettleDevice/kettle/src/kettle_main.c new file mode 100644 index 0000000000000000000000000000000000000000..2837369c1a4c5df4dc33a0b0b296017d5e0dbfd9 --- /dev/null +++ b/CompleteApps/SmartKettleDevice/kettle/src/kettle_main.c @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "common_log.h" +#include "kettle_common_init.h" +#include "kettle_button.h" +#include "kettle_heating_sys.h" +#include "kettle_oled.h" +#include "kettle_main.h" +#include "json/jsonutil.h" + +#include "network_manager_service.h" + +static bool g_buttonFlag = false; + +void KettleShowSettingTemp(uint32 settingTemp, const char *description) +{ + /* If the temperature matches the setting in the macro definition, Chinese characters are displayed. + Otherwise, Decripton is displayed. */ + char str[24]; + LOG_I("kettle setting temp: %d\n", settingTemp); + sprintf_s(str, sizeof(str), "temp : %d", settingTemp); + OledShowStr(X_KETTLE_SHOW_TEMP, Y_KETTLE_SHOW_TEMP, " ", CHAR_SIZE_OF_LANTTICE_8_16); // 清空第2行 + OledShowStr(X_KETTLE_SHOW_TEMP, Y_KETTLE_SHOW_TEMP, str, CHAR_SIZE_OF_LANTTICE_8_16); + OledShowStr(X_KETTLE_SHOW_DISCRITION, Y_KETTLE_SHOW_DISCRITION, " ", + CHAR_SIZE_OF_LANTTICE_8_16); // Clear this line + OledShowStr(X_KETTLE_SHOW_DISCRITION, Y_KETTLE_SHOW_DISCRITION + 1, " ", + CHAR_SIZE_OF_LANTTICE_8_16); + switch (settingTemp) { + case DRINK_WATER: + OledShowStr(X_KETTLE_SHOW_DISCRITION, Y_KETTLE_SHOW_DISCRITION, "708", CHAR_SIZE_OF_LANTTICE_HZ_16_16); + break; + case MILK: + OledShowStr(X_KETTLE_SHOW_DISCRITION, Y_KETTLE_SHOW_DISCRITION, "506", CHAR_SIZE_OF_LANTTICE_HZ_16_16); + break; + case GINGER_TEA: + OledShowStr(X_KETTLE_SHOW_DISCRITION, Y_KETTLE_SHOW_DISCRITION, "405", CHAR_SIZE_OF_LANTTICE_HZ_16_16_1); + break; + case SCENTED_TEA: + OledShowStr(X_KETTLE_SHOW_DISCRITION, Y_KETTLE_SHOW_DISCRITION, "305", CHAR_SIZE_OF_LANTTICE_HZ_16_16_1); + break; + case TEAS: + OledShowStr(X_KETTLE_SHOW_DISCRITION, Y_KETTLE_SHOW_DISCRITION, "304", CHAR_SIZE_OF_LANTTICE_HZ_16_16); + break; + case COFFEE: + OledShowStr(X_KETTLE_SHOW_DISCRITION, Y_KETTLE_SHOW_DISCRITION, "102", CHAR_SIZE_OF_LANTTICE_HZ_16_16_1); + break; + case BOILED_WATER: + OledShowStr(X_KETTLE_SHOW_DISCRITION, Y_KETTLE_SHOW_DISCRITION, "102", CHAR_SIZE_OF_LANTTICE_HZ_16_16); + break; + default: + OledShowStr(X_KETTLE_SHOW_DISCRITION, Y_KETTLE_SHOW_DISCRITION, description, CHAR_SIZE_OF_LANTTICE_8_16); + break; + } + return; +} + +/** + * This function will dealwith the message that receive from FA. It can divide the message into working mode. + * temp time andr description. eg: warm 50 8 milk. And will show the time and description on the Oled screen. + * then use the interface UpdateHeatSysCfg send the these message to heating system. + */ +void ProcessKettleAppMessage(const char *data) +{ + char *json_data = NULL; + char *data1 = NULL; + char *data2 = NULL; + char *settingMode = NULL; + char *settingTemp = NULL; + char *settingTime = NULL; + char *description = NULL; + HeatSysCfg FASetting = {0}; + json_handle json; + + json = parse_json(data); + json_data = get_json_string(json, "message"); + + settingMode = strtok_s((char *)json_data, " ", &data1); + if (settingMode == NULL) { + LOG_E("Receive the operating mode failed. \n"); + return; + } + + if (strcmp(settingMode, "warm") == 0) { + FASetting.mode = WARM_MODE; + } else if (strcmp(settingMode, "boiled") == 0) { + FASetting.mode = BOILED_MODE; + } else { + LOG_E("The operating mode is incorrent\n"); + return; + } + settingTemp = strtok_s(data1, " ", &data2); + if (settingTemp == NULL) { + LOG_E("Receive the temp failed. \n"); + return; + } + FASetting.temp = (unsigned int)atoi(settingTemp); + + settingTime = strtok_s(data2, " ", &description); + if (settingTime == NULL) { + LOG_E("Receive the time failed. \n"); + return; + } + KettleShowSettingTemp(FASetting.temp, description); + UpdateHeatSysCfg(FASetting); + return; +} + +static int NetCfgEventHandle(NET_EVENT_TYPE event, void *data) +{ + switch (event) { + case NET_EVENT_CONNECTTED: + LOG_D("NET_EVENT_CONNECTTED \n"); + OledShowStr(0, 0, " Connected ", 1); + break; + case NET_EVENT_RECV_DATA: + LOG_D("NET_EVENT_RECV_DATA \n"); + if (data == NULL) { + LOG_E("NULL POINT! \n"); + return -1; + } + ProcessKettleAppMessage(data); + break; + default: + break; + } + + return 0; +} + +int RecvHeatEventHandle(HEAT_EVENT *event) +{ + char message[24] = {0}; + LOG_I("event->eType: %d, event->temp: %d, event->stat: %d\n", event->eType, event->temp, event->stat); + switch (event->eType) { + case HEAT_EVENT_CFG_UPDATE: + case HEAT_EVENT_TEMP_CHANGE: + sprintf_s(message, sizeof(message), "%d %d", event->temp, event->stat); + break; + case HEAT_EVENT_TIMER_REACH: + sprintf_s(message, sizeof(message), "timer"); // Scheduled end + break; + default: + break; + } + + NetManagerSendMsg(message); + + return 0; +} + +void ButtonEventHandle(KeyEvent *event) +{ + (void)event; // not use, Designed for expand multiple keys + g_buttonFlag = true; +} + +static void DealButtonEvent(void) +{ + char message[24] = {0}; + if (g_buttonFlag == true) { + sprintf_s(message, sizeof(message), "time"); // Simulated drinking time + NetManagerSendMsg(message); + g_buttonFlag = false; + } +} + +static void *MainTask(const char *arg) +{ + (void)arg; + DeviceInit(); + RegButtonIrq(ButtonEventHandle); + LOG_I("RegButton success.\n"); + HeatSysRegister(RecvHeatEventHandle); + LOG_I("HeatSys success.\n"); + + NetManagerRegister("Kettle_AP", NetCfgEventHandle); + LOG_I("NetCfg success.\n"); + while (1) { + DealButtonEvent(); // Deal with the button status. press or not + usleep(APP_DEMO_KETTLE_SLEEP_TIME_US); // Release the cpu resources + } + return NULL; +} + +void KettleDemoEntry(void) +{ + osThreadAttr_t attr; + attr.name = "kettleMainTask"; + attr.attr_bits = 0U; + attr.cb_mem = NULL; + attr.cb_size = 0U; + attr.stack_mem = NULL; + attr.stack_size = KETTLE_TASK_STACK_SIZE; + attr.priority = KETTLE_TASK_PRIO; + + if (osThreadNew((osThreadFunc_t)MainTask, NULL, &attr) == NULL) { + LOG_E("Falied to create NetCfgTask!\n"); + } + return; +} + +SYS_RUN(KettleDemoEntry); diff --git a/CompleteApps/SmartKettleDevice/kettle/src/kettle_oled.c b/CompleteApps/SmartKettleDevice/kettle/src/kettle_oled.c new file mode 100644 index 0000000000000000000000000000000000000000..3a18a7c5af23eaeb8bfc90627b8dca7020e194cd --- /dev/null +++ b/CompleteApps/SmartKettleDevice/kettle/src/kettle_oled.c @@ -0,0 +1,224 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include "iot_errno.h" +#include "iot_i2c.h" +#include "common_log.h" +#include "kettle_oled.h" +#include "kettle_code_tab.h" + + +static uint8 OledInitCmd[CMD_LENGTH] = { + DISPLAY_OFF, // Display off + SET_LOW_COLUMN_ADDRESS, // ---set low column address + SET_HIGH_COLUMN_ADDRESS, // ---set high column address + SET_START_LINE_ADDRESS, // --set start line address + SET_PAGE_ADDRESS, // --set page address + CONTRACT_CONTROL, // contract control + FULL_SCREEN, // --128 + SET_SEGMENT_REMAP, // set segment remap + NORMAL, + SET_MULTIPLEX, // --set multiplex ratio(1 to 64) + DUTY, // --1/32 duty + SCAN_DIRECTION, // Com scan direction + DISPLAY_OFFSET, // -set display offset + DISPLAY_TYPE, + OSC_DIVISION, // set osc division + DIVISION, + COLOR_MODE_OFF, // set area color mode off + COLOR, + PRE_CHARGE_PERIOD, // set Pre-Charge Period + PERIOD, + PIN_CONFIGUARTION, // set com pin configuartion + CONFIGUARTION, + SET_VCOMH, // set Vcomh + VCOMH, + SET_CHARGE_PUMP_ENABLE, // set charge pump enable + PUMP_ENABLE, + TURN_ON_OLED_PANEL // --turn on oled panel +}; + +/* I2C write Byte */ +static uint32 I2cWriteByte(uint8 regAddr, uint8 cmd) +{ + uint32 status = 0; + uint8 userData = cmd; + uint8 sendUserCmd [2] = {0x00, userData}; + uint8 sendUserData [2] = {0x40, userData}; + + // write cmd + if (regAddr == 0x00) { + status = IoTI2cWrite(WIFI_IOT_OLED_I2C_IDX_0, OLED_ADDRESS, sendUserCmd, sizeof(sendUserCmd)); + if (status != IOT_SUCCESS) { + LOG_E("===== Error: SSD1306 OLED Screen I2C write status = 0x%x! =====\r\n", status); + return status; + } + } else if (regAddr == 0x40) { // write data + status = IoTI2cWrite(WIFI_IOT_OLED_I2C_IDX_0, OLED_ADDRESS, sendUserData, sizeof(sendUserData)); + if (status != IOT_SUCCESS) { + LOG_E("===== Error: SSD1306 OLED Screen I2C write status = 0x%x! =====\r\n", status); + return status; + } + } + return IOT_SUCCESS; +} + +static uint32 WriteCmd(uint8 cmd) +{ + // Oled write cmd + if (IOT_SUCCESS != I2cWriteByte(OLED_ADDRESS_WRITE_CMD, cmd)) { + LOG_E("===== Error!!! Write Cmd : write device address cmd failed %d =====\r\n", __LINE__); + return IOT_FAILURE; + } + return IOT_SUCCESS; +} + +static uint32 WriteData(uint8 I2C_Data) +{ + // Oled write data + if (IOT_SUCCESS != I2cWriteByte(OLED_ADDRESS_WRITE_DATA, I2C_Data)) { + LOG_E("===== Error!!! Write Data : write device address failed %d =====\r\n", __LINE__); + return IOT_FAILURE; + } + return IOT_SUCCESS; +} + +void OledSetPosition(uint8 x, uint8 y) +{ + if (IOT_SUCCESS != WriteCmd(0xb0 + y)) { + LOG_E("WriteCmd Error \n"); + return; + } + if (IOT_SUCCESS != WriteCmd(((x&0xf0)>>SET_POSITION_OFFSET) | 0x10)) { + LOG_E("WriteCmd Error \n"); + return; + } + if (IOT_SUCCESS != WriteCmd(x & 0x0f)) { + LOG_E("WriteCmd Error \n"); + return; + } +} + +void OledFillScreen(uint8 fii_data) +{ + for (uint8 m = 0; m < MAX_LINE_OF_LANTTICE; m++) { + if (IOT_SUCCESS != WriteCmd(0xb0 + m)) { + LOG_E("WriteCmd Error \n"); + return; + } + if (IOT_SUCCESS != WriteCmd(0x00)) { + LOG_E("WriteCmd Error \n"); + return; + } + if (IOT_SUCCESS != WriteCmd(0x10)) { + LOG_E("WriteCmd Error \n"); + return; + } + for (uint8 n = 0; n < Max_Column; n++) { + if (IOT_SUCCESS != WriteData(fii_data)) { + LOG_E("WriteData Error \n"); + return; + } + } + } +} + +void OledShowChar(uint8 x, uint8 y, uint8 chr, uint8 charSize) +{ + uint8 i; + uint8 c = chr - ' '; // calc the offset + + if (charSize == CHAR_SIZE_OF_LANTTICE_8_16) { + OledSetPosition(x, y); + for (i = 0; i < HORI_PIXEL_OF_LANTTICE_8_16; i++) { + WriteData(F8X16[c*CHAR_SIZE_OF_LANTTICE_8_16 + i ]); + } + OledSetPosition(x, y + 1); + for (i = 0; i < HORI_PIXEL_OF_LANTTICE_8_16; i++) { + WriteData(F8X16[c*CHAR_SIZE_OF_LANTTICE_8_16 + i + HORI_PIXEL_OF_LANTTICE_8_16]); + } + } else if (charSize == CHAR_SIZE_OF_LANTTICE_HZ_16_16) { + c = chr - '0'; + OledSetPosition(x, y); + for (i = 0; i < HORI_PIXEL_OF_LANTTICE_HZ_16_16; i++) { + WriteData(HZ_F16X16[c][0][i]); + } + + OledSetPosition(x, y + 1); + for (i = 0; i < HORI_PIXEL_OF_LANTTICE_HZ_16_16; i++) { + WriteData(HZ_F16X16[c][1][i]); + } + } else if (charSize == CHAR_SIZE_OF_LANTTICE_HZ_16_16_1) { + c = chr - '0'; + OledSetPosition(x, y); + for (i = 0; i < HORI_PIXEL_OF_LANTTICE_HZ_16_16_1; i++) { + WriteData(HZ_F16X16_1[c][0][i]); + } + OledSetPosition(x, y + 1); + for (i = 0; i < HORI_PIXEL_OF_LANTTICE_HZ_16_16_1; i++) { + WriteData(HZ_F16X16_1[c][1][i]); + } + } else { + OledSetPosition(x, y); + for (i = 0; i < HORI_PIXEL_OF_LANTTICE_6_8; i++) { + WriteData(F6X8[c][i]); + } + } +} + +void OledShowStr(uint8 x, uint8 y, const char *chr, uint8 charSize) +{ + uint8 j = 0; + if (chr == NULL) { + return; + } + + while (chr[j] != '\0') { + if (x >= LIMIT_HORI_PIXEL) { + LOG_E("please input the correct x parameter\n"); + return; + } + OledShowChar(x, y, chr[j], charSize); + if (charSize == CHAR_SIZE_OF_LANTTICE_HZ_16_16 || charSize == CHAR_SIZE_OF_LANTTICE_HZ_16_16_1) { + x += HORI_PIXEL_OF_LANTTICE_HZ_16_16; + } else { + x += HORI_PIXEL_OF_LANTTICE_8_16; + } + j++; + } +} + +uint32 OledInit(void) +{ + uint32 status; + osDelay(DELAY_100_MS); // 100ms Keep the power supply stable. + for (int i = 0; i < CMD_LENGTH; i++) { + status = WriteCmd(OledInitCmd[i]); + if (status != IOT_SUCCESS) { + LOG_E("Failed to write OledInitCmd: 0x%x \n", OledInitCmd[i]); + return IOT_FAILURE; + } + } + + OledFillScreen(0x00); // The screen off + osDelay(DELAY_10_MS); // 10ms + OledShowStr(HORIZONTAL_COORDINATE_OF_SLOGANS, VERTICAL_COORDINATE_OF_SLOGANS, "OpenHarmony OS", 1); + osDelay(DELAY_500_MS); // The time of keep display + OledShowStr(HORIZONTAL_COORDINATE_OF_SLOGANS, VERTICAL_COORDINATE_OF_SLOGANS, " ", 1); + LOG_I("OledInit succuss\n"); + return IOT_SUCCESS; +} \ No newline at end of file diff --git a/CompleteApps/SmartKettleDevice/kettle/src/kettle_temp_sensor.c b/CompleteApps/SmartKettleDevice/kettle/src/kettle_temp_sensor.c new file mode 100644 index 0000000000000000000000000000000000000000..caa07c98d1b49e56b1dd09ca0dd9be684ae93882 --- /dev/null +++ b/CompleteApps/SmartKettleDevice/kettle/src/kettle_temp_sensor.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include +#include +#include +#include "ohos_types.h" +#include "iot_errno.h" +#include "common_log.h" +#include "kettle_temp_sensor.h" +#include "kettle_main.h" + +#define AHT_REG_ARRAY_LEN (6) +#define AHT_REG_TEMP_BITS_1 (3) +#define AHT_REG_TEMP_BITS_2 (4) +#define AHT_REG_TEMP_BITS_3 (5) +#define AHT_REG_TEMP_OFFSET (16) +#define AHT_REG_TEMP_OFFSET_1 (8) +#define AHT_OC_ARRAY_LEN (6) +#define AHT_SNED_CMD_LEN (3) +#define SENSOR_TASK_STAK_SIZE (1024*4) +#define SENSOR_TASK_PRIORITY (14) +#define AHT_REG_ARRAY_INIT_LEN (1) +#define AHT_CALCULATION (1048576) +#define DECIMAL 10 +#define NUMBER_OF_DECIMAL_POINTS 3 + +int TempSensorInit(void) +{ + uint32 status; + uint8 recvDataInit[AHT_REG_ARRAY_INIT_LEN] = {0}; + uint8 initSendUserCmd[AHT_SNED_CMD_LEN] = {AHT_DEVICE_INIT_CMD, AHT_DEVICE_PARAM_INIT_HIGH, + AHT_DEVICE_PARAM_LOW_BYTE}; + memset_s(&recvDataInit, sizeof(recvDataInit), 0x0, sizeof(recvDataInit)); + status = IoTI2cRead(WIFI_IOT_SENSOR_I2C_IDX_0, (AHT_DEVICE_ADDR<<1) | 0x01, recvDataInit, AHT_REG_ARRAY_INIT_LEN); + if (((recvDataInit[0] != AHT_DEVICE_CALIBRATION_ERR) + && (recvDataInit[0] != AHT_DEVICE_CALIBRATION_ERR_R)) + || (recvDataInit[0] == AHT_DEVICE_CALIBRATION)) { + status = IoTI2cWrite(WIFI_IOT_SENSOR_I2C_IDX_0, (AHT_DEVICE_ADDR<<1) | 0x00, initSendUserCmd, AHT_SNED_CMD_LEN); + usleep(AHT_SLEEP_1S); + return IOT_SUCCESS; + } + return status; +} + +uint32 SensorWrite(uint8 triggerCmd, uint8 highByteCmd, uint8 lowByteCmd) +{ + uint32 status; + uint8 _send_user_cmd[AHT_SNED_CMD_LEN] = {triggerCmd, highByteCmd, lowByteCmd}; + status = IoTI2cWrite(WIFI_IOT_SENSOR_I2C_IDX_0, (AHT_DEVICE_ADDR<<1) | 0x00, _send_user_cmd, AHT_SNED_CMD_LEN); + + return status; +} + +uint32 SensorRead(uint8 type) +{ + uint8 recvData[AHT_REG_ARRAY_LEN] = {0}; + float temper = 0; + uint32 temper_t = 0; + + memset_s(&recvData, sizeof(recvData), 0x0, sizeof(recvData)); + IoTI2cRead(WIFI_IOT_SENSOR_I2C_IDX_0, (AHT_DEVICE_ADDR<<1) | 0x01, recvData, AHT_REG_ARRAY_LEN); + if (type == AHT_TEMPERATURE) { + temper = (float)((recvData[AHT_REG_TEMP_BITS_1] &0x0f)<